AES-GCM加解密中遇到的问题

网上关于GCM算法的介绍和代码都比较多,这里不再赘述,仅记录一下在使用过程中遇到的问题,便于回看查阅。

关于字节拷贝的问题

代码如下:

const char* gcmkey = "helloworld";

unsigned char keyBuf[64] = {0};
memcpy((char*)keyBuf, gcmkey, sizeof(keyBuf)-1);

//AES-GCM加密
// ...

问题描述

在32位android手机上运行正常,在64位手机上解密失败

原因分析

首先怀疑是64位openssl库有问题,但查了一圈无果。

然后调试发现,虽然32位手机正常,但每次加密的结果都不同。顺着这个思路排查,最终查到应该是keyBuf每次都会不一样,传递的gcmkey相同,但keyBuf不同,那只能说明通过sizeof(keyBuf)指定拷贝长度,会多拷贝一些无效的随机脏数据(gcmkey<64时),从而导致了该问题。

那么,还有个问题:为什么32位手机正常呢?

猜测是32位手机,默认的内存值固定,而非随机数据。如果哪位大神知道,还烦请告知一下,不胜感激

解决方案

既然问题明确了,那么改起来就简单了

const char* gcmkey = "helloworld";

unsigned char keyBuf[64] = {0};
memcpy((char*)keyBuf, gcmkey, strlen(gcmkey));

//AES-GCM加密
// ...

这种写法虽然解决了加解密问题,但还有个隐患:若gcmkey的长度大于64,则会导致越界写内存。

其实,第一种写法(使用目标缓存大小作为拷贝长度)就是为了解决越界写内存问题,但是却引入了脏数据问题。

为了解决这两种问题,可以使用原数据长度和目标数据长度两个中较小的一个,作为拷贝长度:

const char* gcmkey = "helloworld";
unsigned char keyBuf[64] = {0};

int len = strlen(gcmkey) < 64 ? strlen(gcmkey) : 64;
memcpy((char*)keyBuf, gcmkey, len);

//AES-GCM加密
// ...

 

关于秘钥长度的问题

AES-GCM的秘钥长度最大是32,可以通过函数EVP_aes_256_gcm的返回值进行查看

EVP_CIPHER* cph = EVP_aes_256_gcm();
	// cph->key_len 32
	// cph->iv_len 12
	// cph->block_size 1
	// ...

所以,秘钥长度大于32时,会被截断;秘钥长度小于32时,要保证keyBuf有固定初值。

总结

AES-GCM加解密,只需要小心处理keyBuf的赋值问题,再按照网上的加解密流程,问题应该就不大了。

你可能感兴趣的:(c++,android,加密解密)