我正在编写C ++服务器函数,它将通过传递带有AES CBC 128位的加密字符串称为java进程。我不能改变这个C ++函数的单一性。
为此我在C ++代码中使用openssl AES_set_decrypt_key()和AES_cbc_encrypt()方法。 但是在AES_cbc_encrypt()的签名中有一个长度参数,我相信它是实际字符串的长度(未加密)。但是,我的C ++代码不知道实际长度。我做错了吗?有人可以帮忙吗?
示例代码如下:
unsigned char* decrypt(unsigned char* l_cInput_ptr)
{
unsigned char key[] = "asdfghjklpoiuytr";
unsigned char iv[] = "asdfghjklpoiuytr";
unsigned char * dec_out = (unsigned char *)malloc(80*sizeof(char));
memset(dec_out, 0, 80);
AES_KEY dec_key;
AES_set_decrypt_key(key,128,&dec_key);
AES_cbc_encrypt(l_cInput_ptr, dec_out, 16, &dec_key, iv, AES_DECRYPT);
....
}
l_cInput_ptr是加密字符串。 decrypt()方法不知道实际字符串的长度。在这种情况下,我刚刚使用了16的虚拟值。我无法改变java代码。
答案 0 :(得分:1)
AES_cbc_encrypt()
长度参数是输入的长度。因此,对于解密,这是加密数据的长度,对于CBC模式下的AES,它总是16字节的倍数(顺便说一下,你的不清楚)代码如何获得unsigned char*
)指向的提供数据的长度。
解密数据的长度相同,并且填充(通常是PKCS#7填充,有时只是添加NULL,但实际上可能是任何东西)。解密后你必须删除这个填充以获得原始明文。
答案 1 :(得分:0)
是的,安德烈是对的,我遇到了同样的问题。如果原始未加密文本长度不是16字节的倍数,则解密数据与原始数据的lehgth相同,而不进行填充。如果原始未加密文本长度是16个字节(n)的倍数,则解密长度为n + 1,填充16个字节,我们需要将其删除。这是代码:
AES_cbc_encrypt(&encrypted, &decrypted, length, &key2, iv2, 0);
length = strlen(decrypted);
if (length > AES_BLOCK_SIZE && (length % AES_BLOCK_SIZE == 0))
{
length = length - AES_BLOCK_SIZE;
memset(decrypted + length, 0, AES_BLOCK_SIZE);
}
printf("xxx %s", decrypted);