Search code examples
node.jsencryptionaesrsanode-crypto

Node decrypt content with private key and padding


So, I have a content which needs to be decrypted with private key and padding AES/ECB/PKCS5Padding.

I tried many libraries, and many examples, but none of them works. Now, this is the one where I managed to finish to the last steps, but im not sure if there is another library that can do this for me.

var absolutePath = path.resolve('./private.txt');
    var privateKey = fs.readFileSync(absolutePath, "utf8");
    var buffer = new Buffer(toDecrypt, "base64");
    var decrypted = crypto.privateDecrypt(privateKey, buffer);
    return decrypted.toString("utf8");

This one throws me error:

0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag 

The second example, slighlty different than the first one, but uses padding (thats what I need, I just wanted to try without it to see if it works):

var stringKey = 'BEGIN RSA PRIVATE KEY-----....';
    var cipherText = 'ENCRYPTEDTEXT';

    // we compute the sha256 of the key
    var hash = crypto.createHash("sha256");
    hash.update(stringKey, "utf8");
    var sha256key = hash.digest();
    var keyBuffer = new Buffer(sha256key);

    var cipherBuffer = new Buffer(cipherText, 'hex');
    var aesDec = crypto.createDecipheriv("aes-256-ecb", keyBuffer, ''); // always use createDecipheriv when the key is passed as raw bytes
    var output = aesDec.update(cipherBuffer, 'binary', 'binary');
    var final = aesDec.final();
    return output + final;

It crashes on the line var final = aesDec.final() and throws error:

digital envelope routines:EVP_DecryptFinal_ex:wrong final block length

Does anybody has knowledge or expirience on how to do this?


Solution

  • We had similar issue.

    We receieved encrypted base 64 string from api and needed to decrypt aes key, and then, with decrypted aes key, we needed to decrypt the payload.

    What we have done:

    1. var bytes = new Buffer(input, 'base64'); this is the encrypted data from server

    var aes = bytes.slice(offset, offset + AES_SIZE); slice byte array to get aes

    `var aesString = aes.toString('binary');` convert it to binary string
    
    1. Use forge library:

    var forge = require('node-forge');

    var pki = require('node-forge').pki;
    
    
    
    
     // Grab private key from file
                                        var absolutePath = path.resolve('../private-key.txt');
                                        var privateKey = fs.readFileSync(absolutePath, "utf8");
    
         // Generate private key object
                                        var private_key = pki.privateKeyFromPem(privateKey);
                                        var result;
        
                                        // Decrypt aes key with private key
                                        try {
                                            result = private_key.decrypt(api.apiSecret, 'RSA-OAEP', {
                                                md: forge.md.sha1.create(),
                                                mgf1: {
                                                    md: forge.md.sha1.create()
                                                }
                                            });
                                        } catch (err) {
                                            console.error(err.message);
                                            return;
                                        }
        
        
    // Build byte array from aes key
                                    var base = new Buffer(result, 'binary');
    
                                    // Generate initialization vector
                                    var iv = forge.random.getBytesSync(api.content.length);
    
                                    // Create decipher object with AES/ECB/PKCS5 padding
                                    var decipher = forge.cipher.createDecipher('AES-ECB', forge.util.createBuffer(base));
                                    decipher.start({ iv: iv });
                                    // Add content for decrypting
                                    decipher.update(forge.util.createBuffer(api.content));
                                    var result = decipher.finish();
                                    // Get json data from decipher object
                                    var data = decipher.output.data;