Linux libcrypto AES-128 CBC Encryption/Decryption 适用于 Ubuntu 但不适用于 Raspberry Pi
Linux libcrypto AES-128 CBC Encryption/Decryption works on Ubuntu but not Raspberry Pi
以下示例在 64 位桌面 Ubuntu 16.04 上正确加密和解密为相同的原始字符串,但是当编译相同的代码并在 Raspberry Pi 上 运行 ( ARM )(还有另一个自定义 Linux ARM 板)它无法解密为原始字符串。 Raspberry Pi 和另一个 ARM 板都解密为相同但不正确的值。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/crypto.h>
/* AES key for Encryption and Decryption */
const static unsigned char aes_key[]={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
/* Print Encrypted and Decrypted data packets */
void print_data(const char *tittle, const void* data, int len);
int main( )
{
/* Input data to encrypt */
unsigned char aes_input[]={0x0,0x1,0x2,0x3,0x4,0x5};
fprintf(stderr,"%s\n",SSLeay_version(SSLEAY_VERSION));
/* Init vector */
unsigned char iv[AES_BLOCK_SIZE];
memset(iv, 0x00, AES_BLOCK_SIZE);
/* Buffers for Encryption and Decryption */
unsigned char enc_out[sizeof(aes_input)];
unsigned char dec_out[sizeof(aes_input)];
/* AES-128 bit CBC Encryption */
AES_KEY enc_key, dec_key;
AES_set_encrypt_key(aes_key, sizeof(aes_key)*8, &enc_key);
AES_cbc_encrypt(aes_input, enc_out, sizeof(aes_input), &enc_key, iv, AES_ENCRYPT);
/* AES-128 bit CBC Decryption */
memset(iv, 0x00, AES_BLOCK_SIZE); // don't forget to set iv vector again, else you can't decrypt data properly
AES_set_decrypt_key(aes_key, sizeof(aes_key)*8, &dec_key); // Size of key is in bits
AES_cbc_encrypt(enc_out, dec_out, sizeof(aes_input), &dec_key, iv, AES_DECRYPT);
/* Printing and Verifying */
print_data("\n Original ",aes_input, sizeof(aes_input)); // you can not print data as a string, because after Encryption its not ASCII
print_data("\n Encrypted",enc_out, sizeof(enc_out));
print_data("\n Decrypted",dec_out, sizeof(dec_out));
return 0;
}
void print_data(const char *tittle, const void* data, int len)
{
printf("%s : ",tittle);
const unsigned char * p = (const unsigned char*)data;
int i = 0;
for (; i<len; ++i)
printf("%02X ", *p++);
printf("\n");
}
Ubuntu 结果:
OpenSSL 1.0.1f 6 Jan 2014
Original : 00 01 02 03 04 05
Encrypted : D5 40 D0 BB 16 1D
Decrypted : 00 01 02 03 04 05
Raspberry Pi 结果:
OpenSSL 1.0.2l 25 May 2017
Original : 00 01 02 03 04 05
Encrypted : D5 40 D0 BB 16 1D
Decrypted : D3 87 81 20 2B B9
自定义看板结果:
OpenSSL 1.1.0f 25 May 2017
Original : 00 01 02 03 04 05
Encrypted : D5 40 D0 BB 16 1D
Decrypted : D3 87 81 20 2B B9
自定义板(已更新 OpenSSL 以匹配 Ubuntu):
OpenSSL 1.0.1f 6 Jan 2014
Original : 00 01 02 03 04 05
Encrypted : D5 40 D0 BB 16 1D
Decrypted : D3 87 81 20 2B B9
为什么开源 libcrypto 在 Ubuntu 和 2 台不同的 ARM 机器上表现不同?
通常在 CBC 模式下,您使用的缓冲区大小是密码块大小的倍数。这是 CBC 的本质,在 CBC 类型例程的每个 openssl 手册页中都提到了它(不幸的是,我在 AES_cbc_encrypt
上找不到手册页或任何文档)。
幸运的是,错误的缓冲区大小似乎在某些平台上有效。要查看实际情况,请为 enc_out
多分配一个字节,并在加密后将多余的字节归零。解密会失败。
unsigned char enc_out[sizeof(aes_input) + 1];
...
AES_cbc_encrypt(aes_input, enc_out, sizeof(aes_input), &enc_key, iv, AES_ENCRYPT);
enc_out[sizeof(aes_input)] = 0;
修改后的代码在我的机器上的输出:
Original : 00 01 02 03 04 05
Encrypted : D5 40 D0 BB 16 1D 00
Decrypted : 89 FB 06 F4 CD 6A
未经修改的代码会产生 "correct" 输出。
以下示例在 64 位桌面 Ubuntu 16.04 上正确加密和解密为相同的原始字符串,但是当编译相同的代码并在 Raspberry Pi 上 运行 ( ARM )(还有另一个自定义 Linux ARM 板)它无法解密为原始字符串。 Raspberry Pi 和另一个 ARM 板都解密为相同但不正确的值。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/crypto.h>
/* AES key for Encryption and Decryption */
const static unsigned char aes_key[]={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
/* Print Encrypted and Decrypted data packets */
void print_data(const char *tittle, const void* data, int len);
int main( )
{
/* Input data to encrypt */
unsigned char aes_input[]={0x0,0x1,0x2,0x3,0x4,0x5};
fprintf(stderr,"%s\n",SSLeay_version(SSLEAY_VERSION));
/* Init vector */
unsigned char iv[AES_BLOCK_SIZE];
memset(iv, 0x00, AES_BLOCK_SIZE);
/* Buffers for Encryption and Decryption */
unsigned char enc_out[sizeof(aes_input)];
unsigned char dec_out[sizeof(aes_input)];
/* AES-128 bit CBC Encryption */
AES_KEY enc_key, dec_key;
AES_set_encrypt_key(aes_key, sizeof(aes_key)*8, &enc_key);
AES_cbc_encrypt(aes_input, enc_out, sizeof(aes_input), &enc_key, iv, AES_ENCRYPT);
/* AES-128 bit CBC Decryption */
memset(iv, 0x00, AES_BLOCK_SIZE); // don't forget to set iv vector again, else you can't decrypt data properly
AES_set_decrypt_key(aes_key, sizeof(aes_key)*8, &dec_key); // Size of key is in bits
AES_cbc_encrypt(enc_out, dec_out, sizeof(aes_input), &dec_key, iv, AES_DECRYPT);
/* Printing and Verifying */
print_data("\n Original ",aes_input, sizeof(aes_input)); // you can not print data as a string, because after Encryption its not ASCII
print_data("\n Encrypted",enc_out, sizeof(enc_out));
print_data("\n Decrypted",dec_out, sizeof(dec_out));
return 0;
}
void print_data(const char *tittle, const void* data, int len)
{
printf("%s : ",tittle);
const unsigned char * p = (const unsigned char*)data;
int i = 0;
for (; i<len; ++i)
printf("%02X ", *p++);
printf("\n");
}
Ubuntu 结果:
OpenSSL 1.0.1f 6 Jan 2014
Original : 00 01 02 03 04 05
Encrypted : D5 40 D0 BB 16 1D
Decrypted : 00 01 02 03 04 05
Raspberry Pi 结果:
OpenSSL 1.0.2l 25 May 2017
Original : 00 01 02 03 04 05
Encrypted : D5 40 D0 BB 16 1D
Decrypted : D3 87 81 20 2B B9
自定义看板结果:
OpenSSL 1.1.0f 25 May 2017
Original : 00 01 02 03 04 05
Encrypted : D5 40 D0 BB 16 1D
Decrypted : D3 87 81 20 2B B9
自定义板(已更新 OpenSSL 以匹配 Ubuntu):
OpenSSL 1.0.1f 6 Jan 2014
Original : 00 01 02 03 04 05
Encrypted : D5 40 D0 BB 16 1D
Decrypted : D3 87 81 20 2B B9
为什么开源 libcrypto 在 Ubuntu 和 2 台不同的 ARM 机器上表现不同?
通常在 CBC 模式下,您使用的缓冲区大小是密码块大小的倍数。这是 CBC 的本质,在 CBC 类型例程的每个 openssl 手册页中都提到了它(不幸的是,我在 AES_cbc_encrypt
上找不到手册页或任何文档)。
幸运的是,错误的缓冲区大小似乎在某些平台上有效。要查看实际情况,请为 enc_out
多分配一个字节,并在加密后将多余的字节归零。解密会失败。
unsigned char enc_out[sizeof(aes_input) + 1];
...
AES_cbc_encrypt(aes_input, enc_out, sizeof(aes_input), &enc_key, iv, AES_ENCRYPT);
enc_out[sizeof(aes_input)] = 0;
修改后的代码在我的机器上的输出:
Original : 00 01 02 03 04 05
Encrypted : D5 40 D0 BB 16 1D 00
Decrypted : 89 FB 06 F4 CD 6A
未经修改的代码会产生 "correct" 输出。