大坑的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; }
blackfeather 2020/9/1 ℃ 1评论