How is an AES key processed when calling CryptoJS.AES.encrypt/decrypt with a non-standard key length?

StackOverflow https://stackoverflow.com/questions/18049802

Question

I am currently having issues with decrypting items in C# that have been encrypted in CryptoJS using keys that are not of length 128, 192, or 256 bits. CryptoJS allows keys of 'odd' lengths to be used during encryption/decryption, but the symmetric algorithm classes in C# (such as RijndaelManaged) do not allow this.

Javascript

var key =  CryptoJS.enc.Utf8.parse("This key is 160 bits"); // Not 128, 192, or 256 bits, but is allowed
var iv = CryptoJS.enc.Hex.parse("101112131415161718191a1b1c1d1e1f");
var result = CryptoJS.AES.encrypt("Encrypt Me!", key, { iv: iv });

// result.ciphertext = 2839aff89d889dd29480b038679fbd6e
// or result.ciphertext.toString(CryptoJS.enc.Base64) = KDmv+J2IndKUgLA4Z5+9bg==

C#

byte[] key = Encoding.UTF8.GetBytes("This key is 160 bits");
byte[] iv = { 0x10, 0x11, 0x12, 0x13,
              0x14, 0x15, 0x16, 0x17,
              0x18, 0x19, 0x1a, 0x1b,
              0x1c, 0x1d, 0x1e, 0x1f };
byte[] encryptMe = Encoding.UTF8.GetBytes("Encrypt Me!");

using (RijndaelManaged rm = new RijndaelManaged())
{
    rm.IV = iv;
    rm.Key = key; //This is not allowed due to the key size being 160 bits. Exception thrown here.

    using (ICryptoTransform ict = rm.CreateEncryptor())
    {
        byte[] encrypted = ict.TransformFinalBlock(encryptMe, 0, encryptMe.Length);
    }
}

My question is what exactly happens to the key in the javascript code to allow it to be used for encryption/decryption? Padding? Truncation? Is the AES implementation in CryptoJS adjusted to work with 'odd' key lengths?

I have tried adjusting the C# code's key by truncating or padding (both the beginning and end) the byte array to no avail. I'm not terribly familiar with javascript syntax and have looked over the CryptoJS source without understanding much of what's happening.

Was it helpful?

Solution

I took a quick look at the CryptoJS sources, and it seems to be the case that it silently does something nonstandard. If this is true, there is no way to replicate what it does using standard AES.

However, to make sure there is no key derivation or such, try doing an alert(result.key); and see if it's the same as your input.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top