3
votes

I am trying to decrypt a string using ColdFusion's Decrypt() function, but am getting an "encodings are not the same..." error.

These are the steps I was instructed to take from the string's source:

  1. Create an MD5 hash of the shared key
  2. Using TripeDES with the cipher of ECB, decrypt the encrypted string with the MD5 hash of the shared key

Code:

<cfset qKey = hash('shared_key','MD5') />
<cfset dc = Decrypt('string_to_decrypt', qkey, 'DESEDE/ECB/PKCS5Padding', 'Base64') />
<cfdump var="#dc#">

Error:

An error occurred while trying to encrypt or decrypt your input string: The input and output encodings are not same.


Update:

Also tried the following, but it throws the same error:

<cfset finalText   = "WVJrOdkntkQ%3d">
<cfset theKey      = "S3C016" />
<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#">  
2
Do not use TrippleDES, it is no longer considered secure and has been replaced with AES (Advanced Encryption Standard) for new work. There is no more diffiiculty in using AES. Do not use ECB mode, it is insecure, see ECB mode, scroll down to the Penguin. You probably need to use PKCS padding in the case the input length is not an exact multiple of the block size.zaph
unfortunately i do not have a choice so I have to work with what the 3rd party source is using.gavin78
OK, the heck with security, it is over-rated. ;-)zaph
Please add that code to your question and not in the comments. It can be formatted much better that way and more visible to others. editMiguel-F
for the formatting to work you need to have at least four spaces in front of the line and each line must start on a new line. See stackoverflow.com/help/formatting. If you are including sensitive information you may want to mask that data (like don't share your actual key).Miguel-F

2 Answers

4
votes

These are the steps I was instructed to take

Honestly, I always find it a little disturbing when I come across a recommendation for using TripleDES these days. As Zach pointed out it is no longer considered secure and was replaced by stronger algorithms like AES. Also, you can clearly see from wiki article images an illustration of why ECB mode is discouraged: "it does not hide data patterns well". (Side note, in the area of hashing MD5 was also surpassed by stronger algorithms a while ago). Bottom line, I strongly suggest discussing the chosen algorithms with whomever gave you the instructions, because they are not very secure.

However, to answer your question, there are a couple of issues:

  1. Your code says the encrypted value is base64 encoded. However, it includes a percent % symbol which is not a valid character for base64. I am guessing that value was url encoded and must be decoded first:

    <cfset encryptedText = urlDecode("WVJrOdkntkQ%3d")>
    
  2. Hash() returns a hexadecimal string. The encrypt() function requires that keys be base64 encoded.

  3. An MD5 hash returns sixteen (16) bytes. While that is a valid key size for TripleDES, the CF/Java implementation only supports 24 byte keys. You need to pad the key with the first eight (8) bytes to make it the proper size.

    <cfset originalKey = hash("S3C016","MD5")>
    <cfset padChars = left(originalKey, 16)>
    <cfset keyBytes = binaryDecode(originalKey & padChars, "hex")>
    <cfset newKeyString = binaryEncode(keyBytes, "base64")>
    

Making the changes above will resolve the error and allow you to decrypt the string successfully. The result should be "20".

    <cfset dc = Decrypt(encryptedText, newKeyString, "DESEDE/ECB/PKCS5Padding", "Base64")  />
    <cfdump var="#dc#">
1
votes

3DES uses a 24-byte key, MD5 produces a 16-bytes. Many times the first 8-bytes are also used for the final 8-bytes. Some implementations do tis automatically, others zero pad, others---who knows.

Try creating a 24-byte key by duplication the first 8-bytes to the 16-bytes produced by MD5.

Encoding the 16-bytes produced by MD5 really does not make sense in a cryptographic sense eventhough it will prodice 24-bytes.