Search code examples
javascriptjavanode.jscryptojs

how to decrypt in nodejs which is encrypted using JAVA


im trying to convert java lambda into javascript lamda. want to convert these encrypt and decrypt method which is written in java to node js or javascript. I have tried to implement using crpto in node

keys are like this

private static String CIPHER_NAME = "AES/CBC/PKCS5PADDING";
private static int CIPHER_KEY_LEN = 16; //128 bits

encrypt method

 private String encrypt(String key, String iv, String data) {
        try {
            if (key.length() <CIPHER_KEY_LEN) {
                int numPad = CIPHER_KEY_LEN - key.length();

                for(int i = 0; i < numPad; i++){
                    key += "0"; //0 pad to len 16 bytes
                }

            } else if (key.length() >CIPHER_KEY_LEN) {
                key = key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
            }


            IvParameterSpec initVector = new IvParameterSpec(iv.getBytes("ISO-8859-1"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("ISO-8859-1"), "AES");

            Cipher cipher = Cipher.getInstance(CIPHER_NAME);
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, initVector);

            byte[] encryptedData = cipher.doFinal((data.getBytes()));

            String base64_EncryptedData = Base64.getEncoder().encodeToString(encryptedData);
            String base64_IV = Base64.getEncoder().encodeToString(iv.getBytes("ISO-8859-1"));

            return base64_EncryptedData + ":" + base64_IV;

        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }

decrypt method

private String decrypt(String key, String data) {
    try {
        if (key.length() < CIPHER_KEY_LEN) {
            int numPad = CIPHER_KEY_LEN - key.length();

            for(int i = 0; i < numPad; i++){
                key += "0"; //0 pad to len 16 bytes
            }

        } else if (key.length() > CIPHER_KEY_LEN) {
            key = key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
        }

        String[] parts = data.split(":");

        IvParameterSpec iv = new IvParameterSpec(Base64.getDecoder().decode(parts[1]));
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("ISO-8859-1"), "AES");

        Cipher cipher = Cipher.getInstance(CIPHER_NAME);
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

        byte[] decodedEncryptedData = Base64.getDecoder().decode(parts[0]);

        byte[] original = cipher.doFinal(decodedEncryptedData);

        return new String(original);
    } catch (Exception ex) {
        ex.printStackTrace();
    }

    return null;
}

I have used this is the solution i made but seems it not working cause i encrypted this using a java code and using node's javascript code to decrypt it.

function decrypt (messagebase64, keyBase64, ivBase64) {

    var key = Buffer.from(keyBase64, 'base64');
    var iv = Buffer.from(ivBase64, 'base64');

    var decipher = crypto.createDecipheriv(getAlgorithm(keyBase64), key, iv);
    decipher.setAutoPadding(false);
    decipher.update(messagebase64, 'base64');
    return decipher.final();
}

find the alogorithm i use this and adding padding if the key is not long enough but this give error that saying length is not enough.

function getAlgorithm(keyBase64) {

    if(keyBase64.length<CIPHER_KEY_LEN){
        var padding = CIPHER_KEY_LEN-keyBase64.length;
        for(var i=0;i<padding;i++){
            keyBase64+="0";
        }
    }else if(keyBase64.length>CIPHER_KEY_LEN){
        keyBase64 =keyBase64.substring(0, CIPHER_KEY_LEN)
    }

    var key = Buffer.from(keyBase64, 'base64');

    switch (key.length) {
        case 16:
            return 'aes-128-cbc';
        case 32:
            return 'aes-256-cbc';

    }

    throw new Error('Invalid key length: ' + key.length);
}

Solution

  • after struggling for a while i have implemented encrypted method and decrypt method which will be identical to java.

    decrypt method

    function decrypt (messagebase64, keyBase64, ivBase64) {
    
        if(keyBase64.length<CIPHER_KEY_LEN){
            var padding = CIPHER_KEY_LEN-keyBase64.length;
            for(var i=0;i<padding;i++){
                keyBase64+="0";
            }
        }else if(keyBase64.length>CIPHER_KEY_LEN){
            keyBase64 =keyBase64.substring(0, CIPHER_KEY_LEN)
        }
    
    
        var key = Buffer.from(keyBase64, 'latin1');
        var iv = Buffer.from(ivBase64, 'base64');
    
        var encryptdata = new Buffer(messagebase64, 'base64');
    
        var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv),
            decoded = decipher.update(encryptdata, 'base64', 'utf8');
    
        decoded += decipher.final('utf8');
    
    
        return decoded
    
    }
    

    encrypt method

    function encrypt(plainText, keyBase64, ivBase64) {
    
        if(keyBase64.length<CIPHER_KEY_LEN){
            var padding = CIPHER_KEY_LEN-keyBase64.length;
            for(var i=0;i<padding;i++){
                keyBase64+="0";
            }
        }else if(keyBase64.length>CIPHER_KEY_LEN){
            keyBase64 =keyBase64.substring(0, CIPHER_KEY_LEN)
        }
    
        var key = Buffer.from(keyBase64, 'latin1');
        var iv = Buffer.from(ivBase64,'latin1');
        var encoded_base64_iv= iv.toString('base64');
    
        var cipher2 = crypto.createCipheriv('aes-128-cbc', key, iv);
        cipher2.write(plainText);
        cipher2.end();
    
        var cipher_text = cipher2.read();
        var encodedString = cipher_text.toString('base64');
    
        var final_encrypted_data = encodedString+":"+encoded_base64_iv;
    
        return final_encrypted_data.toString();
    };