1

Here is the code used to encrypt in coldfusion

<cfset strBase64Value = encrypt(strValue,24 character key,AES) />

It is generating encrypted values like 714FEA9A9A2184769CA49D5133F08580 which seems odd to me considering it is only uppercase and numbers.

What C# library should I use to properly decrypt it ?

Also looking at this information, it seems that by default it uses the UUEncode algorithm to encode.

Should I ask the encrypter to use Base64 as encoding parameter ?

3
  • checkout this SO post and look at some of the referenced links within the accepted answer stackoverflow.com/questions/3226813/… Commented Oct 3, 2014 at 20:55
  • Here is a great article on AES and .NET. blogs.msdn.com/b/shawnfa/archive/2006/10/09/… Commented Oct 3, 2014 at 21:03
  • I tried it and it is throwing [CryptographicException: Length of the data to decrypt is invalid.] System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) +7593325 It seems to be something to do with the encoding. Commented Oct 3, 2014 at 21:19

2 Answers 2

6

It is generating encrypted values like 714FEA9A9A2184769CA49D5133F08580

Then they are using "Hex", not the default "UUEncode". Either "hex" or "base64" is fine. As long as you both agree upon the encoding, it does not really matter.

You can use RijndaelManaged to decrypt the strings. However, the default encryption settings for ColdFusion and C# differ slightly. With the encrypt function:

  • "AES" is short for "AES/ECB/PKCS5Padding"
  • "ECB" mode does not use an IV
  • Key strings are always base64 encoded

NB: Despite the name difference, for the SUN provider, PKCS5Padding (CF/Java) corresponds to PaddingMode.PKCS7 (C#). As mentioned in this thread, the "... SUN provider in Java indicate[s] PKCS#5 where PKCS#7 should be used - "PKCS5Padding" should have been "PKCS7Padding". This is a legacy from the time that only 8 byte block ciphers such as (triple) DES symmetric cipher were available."

So you need to ensure your C# settings are adjusted to match. With that in mind, just decode the encrypted text from hex and the key string from base64. Using the slightly ugly example in the API, just adjust the algorithm settings to match those used by the encrypt() function:

Encrypt with ColdFusion

<cfscript>
    plainText     = "Nothing to see";
    // 128 bit key base64 encoded
    keyInBase64   = "Y25Aju8H2P5DR8mY6B0ezg==";
    // "AES" is short for "AES/ECB/PKCS5Padding"
    encryptedText = encrypt(plainText, keyInBase64, "AES", "hex");
    WriteDump( encryptedText );
    // result: 8889EDF02F181158AAD902AB86C63951 
</cfscript>

Decrypt with C#

byte[] bytes = SomeMethodToConvertHexToBytes( encryptedText );
byte[] key = Convert.FromBase64String( keyInBase64 );

string decryptedText = null;

using (RijndaelManaged algorithm = new RijndaelManaged())
{

    // initialize settings to match those used by CF
    algorithm.Mode = CipherMode.ECB;
    algorithm.Padding = PaddingMode.PKCS7;
    algorithm.BlockSize = 128;
    algorithm.KeySize = 128;
    algorithm.Key = key;

    ICryptoTransform decryptor = algorithm.CreateDecryptor();

    using (MemoryStream msDecrypt = new MemoryStream(bytes))
    {
        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
        {
           using (StreamReader srDecrypt = new StreamReader(csDecrypt))
           {

               decryptedText = srDecrypt.ReadToEnd();
           }
        }
    }
}

Console.WriteLine("Encrypted String: {0}", encryptedText);
Console.WriteLine("Decrypted String: {0}", decryptedText);

Keep in mind you can (and probably should) adjust the settings, such as using the more secure CBC mode instead of ECB. You just need to coordinate those changes with the CF developer.

Sign up to request clarification or add additional context in comments.

5 Comments

The text says that the padding mode is PKCS5, but the code says that it is PKCS7. Is that a mistake?
@WayneConrad - No, but good question. From what I have read, java (confusingly) maintains the old padding descriptor "PKCS5", but internally uses "PKCS7" padding when needed, like for AES. So for CF/java code you would use "PKCS5Padding", which corresponds to PaddingMode.PKCS7C in C#.
@Leigh do you have any insight as to how to do this with UU encoding? stackoverflow.com/questions/38110956/…. I tried it with the above method and am getting an error, "Length of the data to decrypt is invalid." Its probably in the conversion of the UUEncoded password
@PatrickGoode - You just need something to decode the UU string into bytes. (That will replace SomeMethodToConvertHexToBytes). Last I checked C# did not have a core function or library implementing UUEncode. So to do that on the C# side will probably require a third party library. Simpler to re-encode the values as base64, intead of UU, in CF.
ie encryptedBase64 = binaryEncode(binaryDecode(encryptedAsUU, "uu"), "base64")
1

If anyone had similar problem with JAVA I just implemented encryption and decryption of string previously encrypted/decrypted in coldfusion with "Hex" and "tripledes". Here is my code:

private static final String PADDING = "DESede/ECB/PKCS5Padding";
private static final String UTF_F8 = "UTF-8";
private static final String DE_SEDE = "DESede";
private String secretKey;


public String encrypt(String message) throws Exception {

    secretKey = getSecretKey();

    final byte[] secretBase64Key = Base64.decodeBase64(secretKey);
    final SecretKey key = new SecretKeySpec(secretBase64Key, DE_SEDE);
    final Cipher cipher = Cipher.getInstance(PADDING);
    cipher.init(Cipher.ENCRYPT_MODE, key);
    final byte[] plainTextBytes = message.getBytes();
    final byte[] cipherText = cipher.doFinal(plainTextBytes);

    return Hex.encodeHexString(cipherText);
}

public String decrypt(String keyToDecrypt) throws Exception {

    secretKey = getSecretKey();

    byte[] message = DatatypeConverter.parseHexBinary(keyToDecrypt);
    final byte[] secretBase64Key = Base64.decodeBase64(secretKey);
    final SecretKey key = new SecretKeySpec(secretBase64Key, DE_SEDE);
    final Cipher decipher = Cipher.getInstance(PADDING);
    decipher.init(Cipher.DECRYPT_MODE, key);
    final byte[] plainText = decipher.doFinal(message);

    return new String(plainText, UTF_F8);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.