问题
I'm trying to exchange encrypted data between my ASP.NET application and another developer's CF app using TripleDES.
Here's his CF code (fictitious key and IV of course):
<cfset variables.theKey = "rpaSPvIvVLlrcmtzPU9/c67Gkj7yL1S5">
<cfset variables.theIV = BinaryDecode("password","Base64")>
<cfset variables.theAlgorithm = "DESEDE">
<cfset variables.theEncoding = "Base64">
<cfif IsDefined("form.string") and IsDefined("form.method")>
<cfif form.method is "encrypt">
<cfset variables.theString = encrypt(form.string, variables.theKey, variables.theAlgorithm, variables.theEncoding, variables.theIV)>
</cfif>
<cfif form.method is "decrypt">
<cfset variables.theString = decrypt(form.string, variables.theKey, variables.theAlgorithm, variables.theEncoding, variables.theIV)>
</cfif>
<cfoutput><p>Output: #variables.theString#</cfoutput>
</cfif>
Here's my VB.NET (I've left out exception handling, etc.):
Private IV() As Byte = ASCIIEncoding.ASCII.GetBytes("password")
Private EncryptionKey() As Byte = Convert.FromBase64String("rpaSPvIvVLlrcmtzPU9/c67Gkj7yL1S5")
Public Function EncryptString(ByVal Input As String) As String
Dim buffer() As Byte = Encoding.UTF8.GetBytes(Input)
Dim des As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider
des.Key = EncryptionKey
des.IV = IV
Return Convert.ToBase64String(des.CreateEncryptor().TransformFinalBlock(buffer, 0, buffer.Length()))
End Function
Public Function DecryptString(ByVal Input As String) As String
Dim buffer() As Byte = Convert.FromBase64String(Input)
Dim des As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider
des.Key = EncryptionKey
des.IV = IV
Return Encoding.UTF8.GetString(des.CreateDecryptor().TransformFinalBlock(buffer, 0, buffer.Length()))
End Function
We're getting different results.
The obvious thing that comes to mind is that he's using Base64 to create the IV from the password, whereas I'm using ASCII - but if I do this
Private IV() As Byte = Convert.FromBase64String("password")
then .NET is not happy because it's getting a 6-byte array for the IV and it wants 8 bytes.
Any ideas what we're doing wrong - preferably changes I could make to my (VB.NET) code to make this work? Or failing that, a different approach that would work better between the two environments?
回答1:
The default for CF seems to be "DESede/ECB/PKCS5Padding" but in VB.NET they are "DESede/CBC/PKCS7". I am not sure why, but the two paddings (PKCS5 and PKCS7) seem to be compatible.
To get it to work, you either need to change the mode to "ECB" on VB.NET side
Public Function EncryptString(ByVal Input As String) As String
Dim buffer() As Byte = Encoding.UTF8.GetBytes(Input)
Dim des As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider
des.Mode = CipherMode.ECB
des.Key = EncryptionKey
des.IV = IV
Return Convert.ToBase64String(des.CreateEncryptor().TransformFinalBlock(buffer, 0, buffer.Length()))
End Function
..OR change the CF mode and IV to match the VB.NET defaults
<cfset variables.theKey = "rpaSPvIvVLlrcmtzPU9/c67Gkj7yL1S5" />
<cfset variables.theIV = javacast("string", "password").getBytes() />
<cfset variables.theAlgorithm = "DESede/CBC/PKCS5Padding">
<cfset variables.theEncoding = "Base64">
回答2:
Try to use UTF8 encoding for password.
Private IV() As Byte = Encoding.UTF8.GetBytes("password")
来源:https://stackoverflow.com/questions/1474801/tripledes-encryption-net-and-coldfusion-not-playing-nice