1

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?

Herb Caudill
  • 50,043
  • 39
  • 124
  • 173
  • @Herb - Just a guess, but maybe their IV is being ignored. I get the same result in CF with or without the IV. The documentation says "[IV] ..The algorithm must contain a Feedback Mode other than ECB." That seems to suggest the IV is not used unless you supply a different feedback mode. – Leigh Sep 25 '09 at 18:41
  • I had the same problem with a client once (I was on CF, he was on .NET). We eventually gave up and used AES instead and that worked for us. – ryber Oct 02 '09 at 12:48

2 Answers2

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">
Leigh
  • 28,765
  • 10
  • 55
  • 103
0

Try to use UTF8 encoding for password.

Private IV() As Byte = Encoding.UTF8.GetBytes("password")