BlackFeather'S Blog

首页 | |

大坑的aes GCM解密算法

基于openssl库写的aes_gcm解密方法

兼容gcm 128、192、256位,兼容变长iv算法,与python和java的gcmdecrypt方法结果保持一致。

最恶心的地方在iv长度,要手动设置,否则某些情况下会与python或者java的结果不一致(代码的24行)。


std::string AesGCMDecrypt(const std::string &strKey, const std::string &strIV, const std::string &strBuffer, int nPadding/* = 1*/)
{
std::string strRet;
if (strBuffer.empty())
return strRet;

const EVP_CIPHER *cipher;
if (strKey.length() == 16)
cipher = EVP_aes_128_gcm();
else if (strKey.length() == 24)
cipher = EVP_aes_192_gcm();
else if (strKey.length() == 32)
cipher = EVP_aes_256_gcm();
else
return strRet;

unsigned char *pszDecode = new unsigned char[strBuffer.length() + 32];
ZeroMemory(pszDecode, strBuffer.length() + 32);
unsigned char *pszOut = pszDecode;

int nDecodeLen, nTotalLen = 0;
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL);
if (strIV.length() != 12)
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, strIV.length(), NULL);
EVP_DecryptInit_ex(ctx, NULL, NULL, (const unsigned char *)strKey.c_str(), (const unsigned char *)strIV.c_str());
EVP_CIPHER_CTX_set_padding(ctx, nPadding);
EVP_DecryptUpdate(ctx, pszOut, &nDecodeLen, (const unsigned char *)strBuffer.c_str(), strBuffer.length());
nTotalLen = nDecodeLen;
pszOut += nDecodeLen;

EVP_DecryptFinal(ctx, pszOut, &nDecodeLen);
nTotalLen += nDecodeLen;

strRet.assign((const char *)pszDecode, nTotalLen);
delete[] pszDecode;

EVP_CIPHER_CTX_free(ctx);

return strRet;
}



2020/9/1 | Tags:aes,gcm,openssl | C/C++代码 | 查看评论(1)

相关文章:

Powered By Z-Blog  触屏版 | WAP版 | 电脑版