Search code examples
cryptojstripledes

TripleDES .Net to TripleDES (crypto-js) Javascript


I've spent some time looking at all solutions but something still seems off.. The encrypted string I see in .Net does not match the output I see in Cryto-JS. What could be wrong?

    public static void Encrypt()
    {
        string toEncrypt = "123456";
        string key = "hello";

        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
        byte[] keyArray = hashmd5.ComputeHash(UnicodeEncoding.Unicode.GetBytes(key));
        tdes.Key = keyArray;
        tdes.Mode = CipherMode.ECB;

        ICryptoTransform cTransform = tdes.CreateEncryptor();
        byte[] toEncryptArray = UnicodeEncoding.Unicode.GetBytes(toEncrypt);
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        string finalString = Convert.ToBase64String(resultArray);

        Console.WriteLine("Output encrypted .Net: " + finalString);
    }

and the equivalent Javascript using crypto-js is

    Encrypt = () => {
        var CryptoJS = require('crypto-js');
        var text = '123456'
        var key = "hello";

        key = CryptoJS.enc.Utf16LE.parse(key);
        key = CryptoJS.MD5(key)

        var options = {
           mode: CryptoJS.mode.ECB, 
        };

        var textWordArray = CryptoJS.enc.Utf16LE.parse(text); 
        var encrypted = CryptoJS.TripleDES.encrypt(textWordArray, key, options);   
        var base64String = encrypted.toString();    
        console.log('Output JS Encrypted: ' + base64String);   
     }  

I get yGOnLhoVpIHQOCbAn51FTA== in .Net and d5Lg8k8cz68T6akDI0KQrA== in crypto-js.


Solution

  • I have fixed this issue. A console log inside tripledes.js (CryptoJS package) revealed that I was missing 64 more bits in the key after MD5 Hash.

    this._des1 = DES.createEncryptor(WordArray.create(keyWords.slice(0, 2)));
    this._des2 = DES.createEncryptor(WordArray.create(keyWords.slice(2, 4)));
    this._des3 = DES.createEncryptor(WordArray.create(keyWords.slice(4, 6)));
    

    key.words length was 4 instead of 6. So, des3 had an empty wordarray. Solution was to push value of index 0 and 1 into the key word array. With length now being 6, des3 gets the value of des1. i.e keyWords.slice(0, 2) = keyWords.slice(4, 6).

    Encrypt = () => {
        var CryptoJS = require('crypto-js');
        var text = '123456'
        var key = "hello";
    
        key = CryptoJS.enc.Utf16LE.parse(key);
        key = CryptoJS.MD5(key)
        key.words.push(key.words[0], key.words[1]) // FIX FIX FIX
    
        var options = {
           mode: CryptoJS.mode.ECB, 
        };
    
        var textWordArray = CryptoJS.enc.Utf16LE.parse(text); 
        var encrypted = CryptoJS.TripleDES.encrypt(textWordArray, key, options);   
        var base64String = encrypted.toString();    
        console.log('Output JS Encrypted: ' + base64String);   
     }