Search code examples
javascriptjquerycryptography3des

3DES Hexadecimal key in a Javascript encryption function


I have a javascript function using CryptoJS to encrypt a 8bytes block using a 3DES key.

The function is working with the key 01010101010101010101010101010101, but it is not working with the key ADADADADADAD0101ADADADADADAD0202.

    function enc3DES(keyHex){

    var block = "040502CFFFFEFDEE";

    var encrypted = CryptoJS.DES.encrypt(CryptoJS.enc.Hex.parse(block), CryptoJS.enc.Hex.parse(keyHex), {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });

        encrypted = encrypted.ciphertext.toString();
        return encrypted.substr(0, 8*2).toUpperCase();
    }

Using the above function enc3DES(): The block 040502CFFFFEFDEE encrypted with the key 01010101010101010101010101010101 is C9478CAA27ABA56A and this output is correct.

But the same block the block 040502CFFFFEFDEE encrypted with the key ADADADADADAD0101ADADADADADAD0202 is A413ABD86D52DFFB and this output is wrong, the correct one would be F6A1C5ACA15A50C3.

Could you please help me to understand why the function works fine only with the first key ?


Solution

    • 3DES (or TripleDES) is not DES. Therefore CryptoJS.DES has to be replaced by CryptoJS.TripleDES.

    • The 3DES key consists of 3 concatenated DES keys (K1, K2, K3). There are three keying options: 3TDEA (all three keys are different), 2TDEA (2 keys are different and K1 = K3) and the third case that all keys are identical, which gives the same ciphertext as DES. The first key

      01010101010101010101010101010101 
      

      corresponds to the third option (all keys identical), the key

      ADADADADADAD0101ADADADADADAD0202 
      

      corresponds to the second option (2TDEA). Since CryptoJS expects for 3DES a 24 byte key, the keys

      010101010101010101010101010101010101010101010101
      

      and

      ADADADADADAD0101ADADADADADAD0202ADADADADADAD0101 
      

      must be used.

    • Since the plaintext and the ciphertext have the same length, the padding cannot be Pkcs7. Instead of Pkcs7, ZeroPadding can be used, or if the plaintext is always an integer multiple of the blocksize (8 Byte for 3DES), NoPadding. If the padding is changed then the whole ciphertext (instead of a substring) can be returned.