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 ?

crthompson
  • 15,653
  • 6
  • 58
  • 80
bugfixer
  • 55
  • 7
  • checkout this SO post and look at some of the referenced links within the accepted answer http://stackoverflow.com/questions/3226813/how-can-i-decrypt-a-string-using-aes-algorithm-in-c – MethodMan Oct 03 '14 at 20:55
  • Here is a great article on AES and .NET. http://blogs.msdn.com/b/shawnfa/archive/2006/10/09/the-differences-between-rijndael-and-aes.aspx – Steve Oct 03 '14 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. – bugfixer Oct 03 '14 at 21:19

2 Answers2

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.

Community
  • 1
  • 1
Leigh
  • 28,765
  • 10
  • 55
  • 103
  • 1
    The text says that the padding mode is PKCS5, but the code says that it is PKCS7. Is that a mistake? – Wayne Conrad Jan 14 '16 at 13:40
  • 1
    @WayneConrad - No, but good question. From what I have read, java (confusingly) maintains [the old padding *descriptor* "PKCS5"](http://stackoverflow.com/a/25942381/104223), 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 Jan 14 '16 at 21:25
  • @Leigh do you have any insight as to how to do this with UU encoding? http://stackoverflow.com/questions/38110956/cold-fusion-decrypt-in-c-sharp?noredirect=1#comment63678288_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 – Patrick Goode Jul 05 '16 at 13:12
  • 1
    @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. – Leigh Jul 05 '16 at 13:44
  • ie encryptedBase64 = binaryEncode(binaryDecode(encryptedAsUU, "uu"), "base64") – Leigh Jul 05 '16 at 13:56
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);
}