我正在将 AES 加密程序从 Javascript 移植到 C。
我正在使用 OpenSSL。
对于加密,我使用的是 ECB 256 模式。
加密成功,但最终的 Base64 与我在 JS 中得到的结果不对应。
通过使用多个在线工具进行测试,我从 C 版本获得的输出实际上是正确的,但与来自 JS 的输出不同。
然后我意识到这个问题,多亏了这个工具 https://gchq.github.io/CyberChef。
我提供的密钥是一个 MD5 哈希,如下所示: aa8744256a89cba0d77f0686916f8b2e
如果我在 CyberChef 工具中将密钥作为 HEX 字符串 传递,则输出对应于 JS 版本。
C 版本将密钥读取为 UTF 字符串。
如何强制它以十六进制字符串形式读取密钥?
代码如下:
//generating MD5 of key
char keyHash[33];
unsigned char digest[MD5_DIGEST_LENGTH];
MD5((unsigned char*)keyString, strlen(keyString), (unsigned char*)&digest);
for (int i = 0; i < 16; i++)
sprintf(&keyHash[i * 2], "%02x", (unsigned int)digest[i]);
char out[256];
int outlen = 0;
//initializing context
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
//inizializing encryption with 256 ECB Cipher and MD5 Hash as Key
EVP_EncryptInit(ctx, EVP_aes_256_ecb(), keyHash, 0);
//setting padding
EVP_CIPHER_CTX_set_padding(ctx, EVP_PADDING_PKCS7);
//encrypting
EVP_EncryptUpdate(ctx, out, &outlen, user, strlen(user));
EVP_EncryptFinal(ctx, out, &outlen);
EVP_CIPHER_CTX_free(ctx);
//parsing the result to Base64
BIO *mbio = BIO_new(BIO_s_mem());
BIO *b64bio = BIO_new(BIO_f_base64());
BIO_set_flags(b64bio, BIO_FLAGS_BASE64_NO_NL);
BIO *bio = BIO_push(b64bio, mbio);
BIO_write(bio, out, outlen);
BIO_flush(bio);
char* data = NULL;
size_t datalen = 0;
datalen = BIO_get_mem_data(mbio, &data);
data[datalen] = '\0';
//printing the result
printf("encrypted data: [%s]\n", data);