Top
大坑的aes GCM解密算法_C/C++代码_BlackFeather'S Blog
忙忙碌碌,更新不及时诶。

大坑的aes GCM解密算法

C/C++代码 blackfeather 3686

基于openssl库写的aes_gcm解密方法

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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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;
}



评论列表:

jm
真的是巨坑无比,找遍官网、维基、github都没有找到可以用的示例。
中间还尝试了EVP_aead_aes_256_gcm()方法,同样无效。
还好最后找到博主的这篇笔记,感谢!
jm2022/10/17 14:50:00 回复

发表评论:

验证码