网上大部分 SHA256WithRSA 的示例 C++源码实际是 Sha256 后 RSA,与标准的 SHA256WithRSA 签名结果不符,只好自已写了一个,后来者拿走不谢少入坑。
///<summary>
///SignWithRSA 签名,可用于 SHA256WithRSA,MD5withRSA,XXXwithRSA ...
///<![CDATA[
///基于 openssl 库,需要以下头文件及库文件:
///#include <openssl/rsa.h>
///#include <openssl/pem.h>
///#include <openssl/err.h>
///#include <openssl/sha.h>
///#include <openssl/evp.h>
///#pragma comment(lib, "libssl.lib")
///#pragma comment(lib, "libcrypto.lib")
///]]>
///</summary>
///<param name="sData">待签名字符串</param>
///<param name="signtype">签名类型,SHA256WithRSA 时为 EVP_sha256(), MD5withRSA 时为 EVP_md5() ...,具体查看 openssl 头文件定义</param>
///<param name="rsa">RSA 证书,用 PEM_read_RSAPrivateKey(从文件)/PEM_read_bio_RSAPrivateKey(从内存)等函数加载,用 RSA_free(rsa) 释放</param>
///<returns>签名结果 (base64 编码的字符串)</returns>
string SignWithRSA(const char* sData, const EVP_MD* signtype, RSA* rsa)
{
string sResult;
EVP_PKEY* pEvpPkey = ::EVP_PKEY_new();
EVP_MD_CTX* pEvpMdCtx = ::EVP_MD_CTX_new();
if (::EVP_PKEY_assign_RSA(pEvpPkey, rsa) == 1)
{
::EVP_SignInit(pEvpMdCtx, signtype);
::EVP_SignUpdate(pEvpMdCtx, sData, ::strlen(sData));
unsigned int nSignLen = (unsigned int)::EVP_PKEY_size(pEvpPkey);
string sSign(nSignLen, 0);
if (::EVP_SignFinal(pEvpMdCtx, (unsigned char*)sSign.c_str(), &nSignLen, pEvpPkey) == 1)
{
sResult.resize(nSignLen * 2);
int nOutLen = ::EVP_EncodeBlock((unsigned char*)sResult.c_str(), (unsigned char*)sSign.c_str(), nSignLen);
sResult.resize(nOutLen);
}
}
::EVP_MD_CTX_free(pEvpMdCtx);
::EVP_PKEY_free(pEvpPkey);
return sResult;
}版权声明:本文为bigwasp原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。