2

I have To encrypt data using aes-128-ecb in nodejs my code is

I am using Crypto to encrypt data

const crypto = require('crypto');

const secret = '1000060000000000';

const cipher = crypto.createCipher('aes-128-ecb', secret);

const ciphertext = cipher.update('9', 'utf8', 'base64')+cipher.final('base64');

console.log("Cipher text is: " + ciphertext);

the output should be EtgITaHs6lEvEHBipj08Kg== but the output is coming as nNzqejauQBnfiDqznGhZ0Q==

aRvi
  • 2,203
  • 1
  • 14
  • 30
Anshu Rai
  • 21
  • 1
  • 1
  • 2
  • 1
    Use `crypto.createCipheriv('aes-128-ecb', secret, null)` instead of the _deprecated_ [`createCipher()`](https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password_options). The latter uses a KDF, which is obviously not intended for your case. – Topaco Sep 29 '20 at 18:25
  • 1
    **Security warning:** Please don't use ECB mode. Use at least a mode of operation with a random/unpredictable IV so your encryption is semantically secure. Then you should use a mode of operation that also supports authentication, like AES-GCM. Authentication is necessary if you want to detect (malicious) modifications to the ciphertext. This is useful because many modes of operation are malleable. – Artjom B. Sep 30 '20 at 17:24

2 Answers2

5

The problem here is the use of crypto.createCipher, it doesn't use the key directly, but rather a digest.

To quote the documentation:

The implementation of crypto.createCipher() derives keys using the OpenSSL function EVP_BytesToKey with the digest algorithm set to MD5, one iteration, and no salt.

If we use cipher.createCipheriv on the other hand, we can specify the key directly and it will give us the expected output.

Here's an example:

const crypto = require("crypto");

function encrypt(plainText, key, outputEncoding = "base64") {
    const cipher = crypto.createCipheriv("aes-128-ecb", key, null);
    return Buffer.concat([cipher.update(plainText), cipher.final()]).toString(outputEncoding);
}

function decrypt(cipherText, key, outputEncoding = "utf8") {
    const cipher = crypto.createDecipheriv("aes-128-ecb", key, null);
    return Buffer.concat([cipher.update(cipherText), cipher.final()]).toString(outputEncoding);
}

const key = "1000060000000000";
const plainText = "9";
const encrypted = encrypt(plainText, key, "base64");
console.log("Encrypted string (base64):", encrypted);
const decrypted = decrypt(Buffer.from(encrypted, "base64"), key, "utf8")
console.log("Decrypted string:", decrypted);

The output will be

EtgITaHs6lEvEHBipj08Kg==
Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
0

It is late but will help others You can pass any Algorithm i.e. aes-128-cbc , aes-128-ecb

Create a new file and name it as aes-service.js in service folder or anywhere in Node.js application

aes-service.js


    const crypto = require('crypto');
    
    const cryptkey = 'C51GH00SE8499727';
    const iv =  'BDA30EGDH1578F81';
    
    
    async function encrypt(text){
        try {
            var cipher = crypto.createCipheriv('aes-128-cbc',cryptkey,iv);
            var crypted = cipher.update(text,'utf8','base64');  //base64 , hex
            crypted += cipher.final('base64');
            return crypted;
        } catch (err) {
            console.error('encrypt error',err);
            return null;
        }
    }
    
    async function decrypt(encryptdata){
        //Check all Algorithms
        console.log(crypto.getCiphers()); // ['aes-128-cbc', 'aes-128-ccm', ...]
    
        try {
            let decipher = crypto.createDecipheriv('aes-128-cbc',cryptkey,iv)
            decipher.setAutoPadding(false)
            let decoded  = decipher.update(encryptdata,'base64','utf8') //base64 , hex
            decoded  += decipher.final('utf8')
            return decoded
        } catch (err) {
            console.error('decrypt error',err)
            return null
        }
    }
    
    const AesService = {
        encrypt:encrypt,
        decrypt:decrypt,
    }
    module.exports = AesService

Node.js contorller i.e abc.controller.js //Get aes encrypted data from node.js request


    const AesService  = require("./services/aes-service")
    
    exports.getAesEncryptedDatafromReq= async (req, res) => {
       
        try{
            let decryptData = ''
            try{
                const buffers = [];
                for await (const chunk of req) {
                    buffers.push(chunk);
                }
                const dataBuffer = Buffer.concat(buffers).toString();
                const jsonParsedData = JSON.parse(dataBuffer)
                decryptData = jsonParsedData.data
            }catch(err){}
    
           
          
            let decryptedData = await AesService.decrypt(decryptData)
            console.log('decrypted data',decryptedData)
    
            let sendbackdata = {
                "status": 0,
                "anotehr_key":[
                    { "dec":"0", "asc":"1"}
                ]
            }
            sendbackdata = JSON.stringify(sendbackdata)
            let encryptedData = await AesService.encrypt(sendbackdata)
            
              //Check if encrypted performed well
             // let decryptedDataAgain = await AesService.decrypt(encryptedData)
            //console.log('decryptedDataAgain ',decryptedDataAgain)
    
    
            return res.status(201).send({"data":encryptedData})
    
        }catch(err){
            return res.status(500)
        }
    }

Add route

 router.post("/get/aes/encrypted/data/from/req", controller.getAesEncryptedDatafromReq)
Muhammad Shahzad
  • 9,340
  • 21
  • 86
  • 130