Decrypting a string in ColdFusion encrypted with 3DES in C #

It's hard for us to decrypt a string in ColdFusion, which was previously encrypted using 3DES and C #. Here is the code we used to initially encrypt the string:

public static string EncryptTripleDES(string plaintext, string key) { TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider(); MD5CryptoServiceProvider hashMD5 = new MD5CryptoServiceProvider(); DES.Key = hashMD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(key)); DES.Mode = CipherMode.ECB; ICryptoTransform DESEncrypt = DES.CreateEncryptor(); byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(plaintext); string EncString = Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length)); EncString = EncString.Replace("+", "@@12"); return EncString; } 

We tried using the sentences here:

TripleDES Encryption-.NET and ColdFusion don't play well

.. bad luck. Here is our CF code and error:

  <cfset variables.theKey = "blahblah" /> <cfset variables.theAlgorithm = "DESede/CBC/PKCS5Padding"> <cfset variables.theEncoding = "Base64"> <cfset strTest = decrypt(#DB.PASSWORD#, variables.theKey, variables.theAlgorithm, variables.theEncoding)> 

Error: An error occurred while trying to encrypt or decrypt your input string: "Unable to decode the string" blahblah "

So it looks like it is trying to decrypt the key, not the string, but that’s not how the decryption function is described in ColdFusion. Any ideas?

UPDATE: Trying to use the following CF code, but the error returned is still "Error trying to encrypt or decrypt your input string: if the last block is incorrectly populated."

 <cfset dbPassword = "Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL"> <cfset finalText = replace(dbPassword, "@@12", "+", "all")> <cfset theKey = "abcdefgh"> <cfset theKeyInBase64 = toBase64(theKey)> <cfset hashedKey = hash( theKeyInBase64, "md5" )> <cfset padBytes = left( hashedKey, 16 )> <cfset keyBytes = binaryDecode( hashedKey & padBytes , "hex" )> <cfset finalKey = binaryEncode( keyBytes, "base64" )> <cfset decrypted = decrypt( finalText, finalKey, "DESede/ECB/PKCS5Padding", "base64" )> Decrypted String: <cfdump var="#decrypted#"> 

UPDATE:

The solution, if you follow the comments, should have changed:

 <cfset hashedKey = hash( theKeyInBase64, "md5" )> 

To:

 <cfset hashedKey = hash( theKey, "md5" )> 

Last code:

 <cfset dbPassword = "Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL"> <cfset finalText = replace(dbPassword, "@@12", "+", "all")> <cfset theKey = "abcdefgh"> <cfset hashedKey = hash( theKey, "md5" )> <cfset padBytes = left( hashedKey, 16 )> <cfset keyBytes = binaryDecode( hashedKey & padBytes , "hex" )> <cfset finalKey = binaryEncode( keyBytes, "base64" )> <cfset decrypted = decrypt( finalText, finalKey, "DESede/ECB/PKCS5Padding", "base64" )> Decrypted String: <cfdump var="#decrypted#"> 
+4
source share
1 answer

It looks like there are a few extra twists in your C # function that you need to deal with in order to achieve compatibility:

  1. The .NET function modifies the encrypted string. You need to undo these changes so that decrypt recognizes it as a valid base64:

     <!--- reverse replacements in encrypted text ie #DB.Password# ---> <cfset dbPassword = " uAugP@ @12aP4GGBOLCLRqxlNPL1PSHfTNEZ"> <cfset finalText = replace(dbPassword, "@@12", "+", "all")> 
  2. The function also uses a hash that creates a 16-byte key. CF / Java requires a 24-byte key for this algorithm. Thus, you must first hash the key and add it to the desired length . Otherwise, decrypt () will complain that the key is too small.

    Note: CF also expects the last key to be encoded in base64. The error cannot decode the blah blah string, assuming your input key is not in base64.

     <!--- hash and pad the key (ie "blahblah"), then convert to base64 for CF ---> <cfset theKeyInBase64 = "rpaSPvIvVLlrcmtzPU9/c67Gkj7yL1S5"> <cfset hashedKey = hash( theKeyInBase64, "md5" )> <cfset padBytes = left( hashedKey, 16 )> <cfset keyBytes = binaryDecode( hashedKey & padBytes , "hex" )> <cfset finalKey = binaryEncode( keyBytes, "base64" )> 
  3. Finally, the feedback modes must match. Because .NET code uses the less secure ECB , CF code must also use this mode.

     <!--- .net code uses the less secure ECB mode ---> <cfset decrypted = decrypt( finalText, finalKey, "DESede/ECB/PKCS5Padding", "base64" )> Decrypted String: <cfdump var="#decrypted#"> 
  4. Another issue worth paying attention to is coding. In CF, encryption / decryption always interprets the input string as UTF8, while the .NET function uses ASCII . For full compatibility, both parties must use the same encoding, in this case UTF8.


Update:

I checked the above with an arbitrary 8-character key (instead of the base64 string), and CF9 still decrypted the string properly.

 // .NET Code String text = "some text to encrypt"; String key = "abcdefgh"; String encrypted = EncryptTripleDES(text, key); // result: encrypted=Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL Console.WriteLine("encrypted={0}", encrypted); <!--- same code, only the encrypted text and key changed ---> <cfset dbPassword = "Hx41SYUrmnFPa31QCH1ArCHN1YOF8IAL"> <cfset finalText = replace(dbPassword, "@@12", "+", "all")> <cfset theKey = "abcdefgh"> <cfset hashedKey = hash( theKey, "md5" )> .... 
+5
source

Source: https://habr.com/ru/post/1395431/


All Articles