简体   繁体   中英

Crypto++ and node.js combination

I'm having problems with getting data encrypted in c++, sent to Node.js server and decrypt it there. I'm using Crypto++ which works fine if I encrypt it and decrypt it. I tried various modes but nothing seemed to help.

I set key as 32x 'A' and IV as 16x '\\0' just for getting consistent data

This is code in c++

AutoSeededRandomPool rand;

// Generate a random key
SecByteBlock key(0x00, AES::MAX_KEYLENGTH);
//rand.GenerateBlock(key, key.size());
memset(key.BytePtr(), 'A', key.size());

// Generate a random IV
byte iv[AES::BLOCKSIZE];
//rand.GenerateBlock(iv, AES::BLOCKSIZE);
memset(iv, 0, AES::BLOCKSIZE);

char plainText[] = "AAAAAAAAAAAAAAA";
int messageLen = (int)strlen(plainText) + 1;

CFB_Mode<AES>::Encryption cfbEncryption(key, key.size(), iv);
cfbEncryption.ProcessData((byte*)plainText, (byte*)plainText, messageLen);

/*CFB_Mode<AES>::Decryption cfbDecryption(key, key.size(), iv);
cfbDecryption.ProcessData((byte*)plainText, (byte*)plainText, messageLen);*/

unsigned int messageLength = messageLen + key.size();
const auto testData = std::vector<byte>(sizeof(unsigned int) + messageLength);

memcpy((void*)&testData[0], reinterpret_cast<void*>(&messageLength), sizeof(unsigned int));
memcpy((void*)&testData[4], (void*)key.BytePtr(), key.size());
memcpy((void*)&testData[4+key.size()], (void*)plainText, messageLen);

testClient.Send(testData);

testClient.Disconnect();

And this is the code in Node.js

socket.on('data', (data) => {

        var messageSizeBuffer = data.slice(0, 4);
        var messageKeyBuffer = data.slice(4, 36);
        var messageDataBuffer = data.slice(36);

        var decipher = crypto.createDecipher('AES-256-CFB', messageKeyBuffer)
        var dec = Buffer.concat([decipher.update(messageDataBuffer) , decipher.final()]);

        console.log(dec.toString());
    });

I needed to use createDecipheriv and provide the same Initialization Vector as used in encryption. Beware of hardcoded key and iv, since this is used only for getting consistent data on the other side. Use random generated key and iv.

Code looks like this now

C++

AutoSeededRandomPool rand;

// Generate a random key
SecByteBlock key(0x00, AES::MAX_KEYLENGTH);
//rand.GenerateBlock(key, key.size());
memset(key.BytePtr(), 'A', key.size());

// Generate a random IV
byte iv[AES::BLOCKSIZE];
//rand.GenerateBlock(iv, AES::BLOCKSIZE);
memset(iv, 0, AES::BLOCKSIZE);

char plainText[] = "AAAAAAAAAAAAAAA";
int messageLen = (int)strlen(plainText) + 1;

CFB_Mode<AES>::Encryption cfbEncryption(key, key.size(), iv);
cfbEncryption.ProcessData((byte*)plainText, (byte*)plainText, messageLen);


unsigned int messageLength = messageLen + key.size() + AES::BLOCKSIZE;
const auto testData = std::vector<byte>(sizeof(unsigned int) + messageLength);

auto currentIndex = 0;
memcpy((void*)&testData[currentIndex], reinterpret_cast<void*>(&messageLength), sizeof(unsigned int));
currentIndex += sizeof(unsigned int);
memcpy((void*)&testData[currentIndex], (void*)key.BytePtr(), key.size());
currentIndex += key.size();
memcpy((void*)&testData[currentIndex], iv, AES::BLOCKSIZE);
currentIndex += AES::BLOCKSIZE;
memcpy((void*)&testData[currentIndex], (void*)plainText, messageLen);

testClient.Send(testData);

testClient.Disconnect();

Node.js

socket.on('data', (data) => {
    var messageSizeBuffer = data.slice(0, 4);
    var messageKeyBuffer = data.slice(4, 36);
    var messageIvBuffer = data.slice(36, 52);
    var messageDataBuffer = data.slice(52);

    var decipher = crypto.createDecipheriv('AES-256-CFB', messageKeyBuffer, messageIvBuffer)
    var dec = Buffer.concat([decipher.update(messageDataBuffer) , decipher.final()]);

    console.log(dec.toString());
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM