Mihir Aryan
Mihir Aryan

Reputation: 29

Encryption in C++ using Openssl and decryption using CryptoJs in Nodejs

I have this code where the secret_key is of 32 length, cipherText variable will have the encrypted data which need to be decoded

const secret_key = "Whispersofthewindechoedthroughth";

const decryptData = (cipherText) => {
    const bytes = CryptoJS.AES.decrypt(cipherText, secret_key);
    let message = bytes.toString(CryptoJS.enc.Utf8);
    return message;
};
console.log("decrypt: " +decryptData(cipherText));

Can anyone suggest the solutions?

I attempted to encrypt data in C++ so that it could be decrypted in Node.js using CryptoJS. I used PKCS5_PBKDF2_HMAC to generate a 32-byte key and initialized the IV as 0 with a size of 16 bytes. MD5 was used for hashing in PKCS5_PBKDF2_HMAC. For encryption, I employed EVP_aes_256_cbc(), and for base64 encoding, I utilized OpenSSL BIOs. However, decryption failed in Node.js.

In Nodejs to encrypt the data, we make this function:- The message is 10 digit number, SecuritySalt length is 128, secret_key length is 32

var CryptoJS = require("crypto-js");
SecuritySalt = "Amidst the bustling city streets, a solitary figure found solace in the melody of raindrops dancing upon the cobblestones.sdwe2q";
secret_key = "Whispersofthewindechoedthroughth";
const encryptData = (message) => {
    return CryptoJS.AES.encrypt(
        SecuritySalt + message,
        secret_key 
     ).toString();
};
let message = "1111111111";
console.log("encrypt message :" + encryptData(message));

I need this same implementation in c++ using openssl.

Upvotes: 2

Views: 228

Answers (1)

Reece Harris
Reece Harris

Reputation: 149

Cpp

#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <string.h>

std::string encryptData(const std::string& message) {
    const std::string secret_key = "Whispersofthewindechoedthroughth";
    const std::string salt = "Amidst the bustling city streets, a solitary figure found solace in the melody of raindrops dancing upon the cobblestones.sdwe2q";
    const std::string data = salt + message;

    unsigned char key[32];
    PKCS5_PBKDF2_HMAC(secret_key.c_str(), secret_key.size(),
                      reinterpret_cast<const unsigned char*>(salt.c_str()), salt.size(),
                      1000, EVP_md5(), sizeof(key), key);

    unsigned char iv[16] = {0};
    unsigned char cipherText[1024] = {0};
    int cipherText_len;

    EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
    EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);

    EVP_EncryptUpdate(ctx, cipherText, &cipherText_len,
                      reinterpret_cast<const unsigned char*>(data.c_str()), data.size());

    int final_len;
    EVP_EncryptFinal_ex(ctx, cipherText + cipherText_len, &final_len);
    cipherText_len += final_len;

    EVP_CIPHER_CTX_free(ctx);

    BIO* b64 = BIO_new(BIO_f_base64());
    BIO* bmem = BIO_new(BIO_s_mem());
    b64 = BIO_push(b64, bmem);
    BIO_write(b64, cipherText, cipherText_len);
    BIO_flush(b64);

    BUF_MEM* bptr;
    BIO_get_mem_ptr(b64, &bptr);

    std::string encryptedData(bptr->data, bptr->length);
    BIO_free_all(b64);

    return encryptedData;
}

You should add appropriate error checking to ensure the code behaves correctly in all situations.

Node

var CryptoJS = require("crypto-js");

const secret_key = "Whispersofthewindechoedthroughth";
const salt = "Amidst the bustling city streets, a solitary figure found solace in the melody of raindrops dancing upon the cobblestones.sdwe2q";

const decryptData = (cipherText) => {
    let decodedCipherText = CryptoJS.enc.Base64.parse(cipherText);
    let salt = CryptoJS.enc.Utf8.parse(salt);
    let key = CryptoJS.PBKDF2(secret_key, salt, { keySize: 256/32, iterations: 1000 });

    let iv = CryptoJS.lib.WordArray.create(decodedCipherText.words.slice(0, 4));
    let encryptedMessage = CryptoJS.lib.WordArray.create(decodedCipherText.words.slice(4));

    let decryptedBytes = CryptoJS.AES.decrypt({ ciphertext: encryptedMessage }, key, { iv: iv });
    let message = decryptedBytes.toString(CryptoJS.enc.Utf8);

    return message;
};

assumes that the IV is the first 16 bytes of the decoded cipherText, and the rest is the encrypted message. This matches the C++ code provided earlier. If your C++ code uses a different arrangement.

Upvotes: 0

Related Questions