I recently needed to achieve interoperability between ColdFusion and .NET in terms of encryption; in this case, consuming a ColdFusion web service in .NET.
I used the Adobe article, Strong encryption in ColdFusion MX 7, as a resource.
Although the encrypt function takes IVorSalt (initialization vector) as an optional argument, we need to explicitly set this value, as we’ll be using it in .NET to perform the decryption.
Here is the ColdFusion code to perform the encryption:
<cfset var key = "dVwuCuBX0LIrSYQbG38f9w==" /><!-- Key in base 64 -->
<cfset var algorithm = "AES/CBC/PKCS5Padding" />
<cfset var encoding = "Base64" />
<cfset var IV = BinaryDecode("7fe8585328e9ac7b28e9ac7b748209b0", "hex") /><!-- Initialization Vector in hexadecimal -->
<cfset password = encrypt(password, key, algorithm, encoding, IV) />
<cfreturn password />
And here is the VB.NET code to perform the decryption:
Dim key() As Byte = Convert.FromBase64String("dVwuCuBX0LIrSYQbG38f9w==")
Dim iv() As Byte = New Byte() {&H7F, &HE8, &H58, &H53, &H28, &HE9, &HAC, &H7B, &H28, &HE9, &HAC, &H7B, &H74, &H82, &H9, &HB0}
Dim password As String = DecryptAES(encryptedPassword, key, iv)
Private Function DecryptAES(ByVal cipherText As String, ByVal key() As Byte, ByVal iv() As Byte) As String
Dim cipherBytes() As Byte = Convert.FromBase64String(cipherText)
Dim ms As MemoryStream = New MemoryStream()
Dim alg As Rijndael = Rijndael.Create()
alg.Key = key
alg.IV = iv
Dim cs As CryptoStream = New CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write)
cs.Write(cipherBytes, 0, cipherBytes.Length)
cs.Close()
Dim decryptedData() As Byte = ms.ToArray()
Dim decryptedText As String = System.Text.ASCIIEncoding.ASCII.GetString(decryptedData)
Return decryptedText
End Function
Just for reference, the corresponding encrypt function in .NET is provided below.
Private Function EncryptAES(ByVal clearText As String, ByVal key() As Byte, ByVal iv() As Byte) As String
Dim clearBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(clearText)
Dim ms As MemoryStream = New MemoryStream()
Dim alg As Rijndael = Rijndael.Create()
alg.Key = key
alg.IV = iv
Dim cs As CryptoStream = New CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write)
cs.Write(clearBytes, 0, clearBytes.Length)
cs.Close()
Dim encryptedData() As Byte = ms.ToArray()
Dim encryptedText As String = Convert.ToBase64String(encryptedData)
Return encryptedText
End Function
In .NET, CipherMode.CBC is the default setting for the Mode (termed Feedback Mode in ColdFusion) property of the Rijndael object, and PaddingMode.PKCS7 is the default Padding value. Fortunately, PKCS7 is an extension of the PKCS5 padding scheme, so we are able to decipher the ColdFusion-encrypted value in .NET.
Throws error: “Specified initialization vector (IV) does not match the block size for this algorithm” when decrypting (line 11).
Aes requires 16 byte length IV
Comment by mipo — November 9, 2010 @ 5:13 am
Thanks for the correction mipo – I amended the post to reflect this. (I originally wrote the post on the basis of some ColdFusion code I had, which was not consistent with the VB.NET code I had, so I had to guess which one was correct.)
Comment by admin — November 11, 2010 @ 11:04 am