views:

819

answers:

2

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?

A: 

Try to use UTF8 encoding for password.

Private IV() As Byte = Encoding.UTF8.GetBytes("password")
Alexey Shirshov
No dice. The password is all ASCII anyway, so Encoding.UTF8.GetBytes produces the same result as Encoding.Ascii.GetBytes.
Herb Caudill
What happens when you try it from VB.NET without the IV?
Leigh
+1  A: 

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">
Leigh
Thanks, I'll give this a try.
Herb Caudill