I am working on client-server communications and am stuck on making sure that both sides come up with the same encrypted token value. Cannot figure out why they are different. The keys and initialization vectors along with the message itself are all the same.
Here is the function that does encryption in client code:
int main()
{
try
{
std::string message = "HelloWorld";
while ((message.size() & 0xf) != 0xf)
message += " ";
size_t inputslength = message.length();
unsigned char aes_input[inputslength];
memset(aes_input, 0, inputslength/8);
strcpy((char*) aes_input, message.c_str());
unsigned char iv[] = {'0','f','9','3','8','7','b','3','f','9','4','b','f','0','6','f'};
unsigned char aes_key[] = {'Z','T','k','0','Y','T','U','5','Y','j','N','h','M','j','k','4','N','G','I','3','N','m','I','x','N','W','E','x','N','z','d','i'};
// buffers for encryption and decryption
const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
unsigned char enc_out[encslength];
unsigned char dec_out[inputslength];
memset(enc_out, 0, sizeof(enc_out));
memset(dec_out, 0, sizeof(dec_out));
AES_KEY enc_key, dec_key;
AES_set_encrypt_key(aes_key, AES_KEYLENGTH, &enc_key);
AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv, AES_ENCRYPT);
AES_set_decrypt_key(aes_key, AES_KEYLENGTH, &dec_key);
AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv, AES_DECRYPT);
printf("original:\t");
hex_print(aes_input, sizeof(aes_input));
printf("encrypt:\t");
hex_print(enc_out, sizeof(enc_out));
printf("decrypt:\t");
hex_print(dec_out, sizeof(dec_out));
std::stringstream ss;
for(int i = 0; i < encslength; i++)
{
ss << enc_out[i];
}
return 0;
}
}
Output
original: 48 65 6C 6C 6F 57 6F 72 6C 64 20 20 20 20 20
encrypt: 72 70 A2 0D FB A1 65 15 17 97 6E 5D 36 23 E2 FA
decrypt: 0A 73 F7 52 AC C1 68 54 1D CA 7A 1F 70 33 F4
Meanwhile.. on the server:
function encryptToken(token)
{
const iv = '0f9387b3f94bf06f';
const key = 'ZTk0YTU5YjNhMjk4NGI3NmIxNWExNzdi';
console.log("key len: " + key.length);
const encrypt = (value) => {
const cipher = crypto.createCipheriv('AES-256-CBC', key, iv);
let encrypted = cipher.update(value, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
};
console.log('Encrypteddd value: ', encrypt('HelloWorld'));
}
Output
Encrypteddd value: 0c491f8c5256b9744550688fc54926e8
Before trying CBC-256 for encryption, I tried the simpler encryption mode, ECB-128 and it all comes down to the same problem. Different encryption tokens produced on client and server side which results in not being able to decrypt what comes from the server side. Any brainstorming tips will help please. I am running out of ideas, thanks.
Update 12.26 -
After taking advice on the init vector and array length on client side.. here is my updated code with output:
int main()
{
try
{
std::string message = "HelloWorld";
while ((message.size() & 0xf) != 0xf)
message += " ";
size_t inputslength = message.length();
unsigned char aes_input[inputslength+1];
memset(aes_input, 0, inputslength/8);
strcpy((char*) aes_input, message.c_str());
unsigned char iv[] = {0x0f, 0x93, 0x87, 0xb3, 0xf9, 0x4b, 0xf0, 0x6f};
unsigned char aes_key[] = {'Z','T','k','0','Y','T','U','5','Y','j','N','h','M','j','k','4','N','G','I','3','N','m','I','x','N','W','E','x','N','z','d','i'};
// buffers for encryption and decryption
const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
unsigned char enc_out[encslength];
unsigned char dec_out[inputslength];
memset(enc_out, 0, sizeof(enc_out));
memset(dec_out, 0, sizeof(dec_out));
AES_KEY enc_key, dec_key;
AES_set_encrypt_key(aes_key, AES_KEYLENGTH, &enc_key);
AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv, AES_ENCRYPT);
AES_set_decrypt_key(aes_key, AES_KEYLENGTH, &dec_key);
AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv, AES_DECRYPT);
printf("original:\t");
hex_print(aes_input, sizeof(aes_input));
printf("encrypt:\t");
hex_print(enc_out, sizeof(enc_out));
printf("decrypt:\t");
hex_print(dec_out, sizeof(dec_out));
std::stringstream ss;
for(int i = 0; i < encslength; i++)
{
ss << enc_out[i];
}
return 0;
}
}
//Output:
original: 48 65 6C 6C 6F 57 6F 72 6C 64 00
encrypt: 54 CD 98 20 59 D9 7B 2D D4 23 ED EC D0 13 97 59
Nodejs code has not changed and this remains the output:
Encrypteddd value: 0c491f8c5256b9744550688fc54926e8