CryptoAPI与openssl数字签名与验证交互
2014-03-19 15:43
295 查看
昨天写过了RSA非对称加密解密的交互方式,
其实数字签名也是RSA非对称加密,只不过用私钥加密的,再加上个hash摘要
CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互已经提到关于证书和私钥的数据以及对象获取,这里就不再重复讨论
1.openssl的签名及验证
[cpp] view plaincopyprint?
void opensslSigner::sign(EVP_PKEY* evpKey,BYTE** signValue,unsigned int &signLen,BYTE* text,int textLen)
{
EVP_MD_CTX mdctx; //摘要算法上下文变量
if(evpKey == NULL)
{
printf("EVP_PKEY_new err\n");
return;
}
//以下是计算签名的代码
EVP_MD_CTX_init(&mdctx); //初始化摘要上下文
if(!EVP_SignInit_ex(&mdctx,EVP_md5(),NULL)) //签名初始化,设置摘要算法
{
printf("err\n");
EVP_PKEY_free(evpKey);
return;
}
if(!EVP_SignUpdate(&mdctx,text,textLen)) //计算签名(摘要)Update
{
printf("err\n");
EVP_PKEY_free(evpKey);
return;
}
if(!EVP_SignFinal(&mdctx,*signValue,&signLen,evpKey)) //签名输出
{
printf("err\n");
EVP_PKEY_free(evpKey);
return;
}
printf("消息\"%s\"的签名值是:\n",text);
printByte(*signValue,signLen);
printf("\n");
EVP_MD_CTX_cleanup(&mdctx);
}
void opensslSigner::verify(EVP_PKEY* evpKey,BYTE* text,unsigned int textLen,BYTE* signValue,unsigned int signLen)
{
ERR_load_EVP_strings();
EVP_MD_CTX mdctx; //摘要算法上下文变量
EVP_MD_CTX_init(&mdctx); //初始化摘要上下文
if(!EVP_VerifyInit_ex(&mdctx, EVP_md5(), NULL)) //验证初始化,设置摘要算法,一定要和签名一致
{
printf("EVP_VerifyInit_ex err\n");
EVP_PKEY_free(evpKey);
return;
}
if(!EVP_VerifyUpdate(&mdctx, text, textLen)) //验证签名(摘要)Update
{
printf("err\n");
EVP_PKEY_free(evpKey);
return;
}
if(!EVP_VerifyFinal(&mdctx,signValue,signLen,evpKey))
{
printf("verify err\n");
EVP_PKEY_free(evpKey);
EVP_MD_CTX_cleanup(&mdctx);
return;
}
else
{
printf("验证签名正确.\n");
}
//释放内存
EVP_PKEY_free(evpKey);
EVP_MD_CTX_cleanup(&mdctx);
}
2.CryptoAPI的签名验证
依然是私钥的问题,没时间再去尝试导入私钥,暂且只写验证
因为也是RSA加密,所以同样要注意字节排列方式,具体看RSA加密的交互部分
[cpp] view plaincopyprint?
void verify(HCRYPTPROV hProv,PCCERT_CONTEXT cert,BYTE* text,unsigned long len,BYTE* signValue,unsigned long signLen)
{
//反序与openssl一致
for(int i = 0 ; i < signLen / 2;i++)
{
BYTE temp = signValue[i];
signValue[i] = signValue[signLen - i - 1];
signValue[signLen - i - 1] = temp;
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hProv, // 容器句柄
CALG_MD5, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
printf("CryptCreateHash error:0X%x.\n",GetLastError());
return;
}
// 计算数据摘要
if(CryptHashData(hHash, text, len, 0) == 0)
{
printf("CryptHashData error:0X%x.\n",GetLastError());
return;
}
if(cert == NULL)
{
printf("pCertContext == NULL:0X%x.\n",GetLastError());
return;
}
//获取公钥句柄
HCRYPTKEY hPubKey;
if(!CryptImportPublicKeyInfo(hProv, cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, &hPubKey))
{
printf("CryptImportPublicKeyInfo error:0X%x.\n",GetLastError());
return;
}
//验证签名
if(!CryptVerifySignature(hHash, signValue, signLen, hPubKey, NULL, 0))
{
printf("CryptVerifySignature error:0X%x.\n",GetLastError());
return;
}
cout << "sign verify successfully" << endl;
其实数字签名也是RSA非对称加密,只不过用私钥加密的,再加上个hash摘要
CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互已经提到关于证书和私钥的数据以及对象获取,这里就不再重复讨论
1.openssl的签名及验证
[cpp] view plaincopyprint?
void opensslSigner::sign(EVP_PKEY* evpKey,BYTE** signValue,unsigned int &signLen,BYTE* text,int textLen)
{
EVP_MD_CTX mdctx; //摘要算法上下文变量
if(evpKey == NULL)
{
printf("EVP_PKEY_new err\n");
return;
}
//以下是计算签名的代码
EVP_MD_CTX_init(&mdctx); //初始化摘要上下文
if(!EVP_SignInit_ex(&mdctx,EVP_md5(),NULL)) //签名初始化,设置摘要算法
{
printf("err\n");
EVP_PKEY_free(evpKey);
return;
}
if(!EVP_SignUpdate(&mdctx,text,textLen)) //计算签名(摘要)Update
{
printf("err\n");
EVP_PKEY_free(evpKey);
return;
}
if(!EVP_SignFinal(&mdctx,*signValue,&signLen,evpKey)) //签名输出
{
printf("err\n");
EVP_PKEY_free(evpKey);
return;
}
printf("消息\"%s\"的签名值是:\n",text);
printByte(*signValue,signLen);
printf("\n");
EVP_MD_CTX_cleanup(&mdctx);
}
void opensslSigner::verify(EVP_PKEY* evpKey,BYTE* text,unsigned int textLen,BYTE* signValue,unsigned int signLen)
{
ERR_load_EVP_strings();
EVP_MD_CTX mdctx; //摘要算法上下文变量
EVP_MD_CTX_init(&mdctx); //初始化摘要上下文
if(!EVP_VerifyInit_ex(&mdctx, EVP_md5(), NULL)) //验证初始化,设置摘要算法,一定要和签名一致
{
printf("EVP_VerifyInit_ex err\n");
EVP_PKEY_free(evpKey);
return;
}
if(!EVP_VerifyUpdate(&mdctx, text, textLen)) //验证签名(摘要)Update
{
printf("err\n");
EVP_PKEY_free(evpKey);
return;
}
if(!EVP_VerifyFinal(&mdctx,signValue,signLen,evpKey))
{
printf("verify err\n");
EVP_PKEY_free(evpKey);
EVP_MD_CTX_cleanup(&mdctx);
return;
}
else
{
printf("验证签名正确.\n");
}
//释放内存
EVP_PKEY_free(evpKey);
EVP_MD_CTX_cleanup(&mdctx);
}
2.CryptoAPI的签名验证
依然是私钥的问题,没时间再去尝试导入私钥,暂且只写验证
因为也是RSA加密,所以同样要注意字节排列方式,具体看RSA加密的交互部分
[cpp] view plaincopyprint?
void verify(HCRYPTPROV hProv,PCCERT_CONTEXT cert,BYTE* text,unsigned long len,BYTE* signValue,unsigned long signLen)
{
//反序与openssl一致
for(int i = 0 ; i < signLen / 2;i++)
{
BYTE temp = signValue[i];
signValue[i] = signValue[signLen - i - 1];
signValue[signLen - i - 1] = temp;
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hProv, // 容器句柄
CALG_MD5, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
printf("CryptCreateHash error:0X%x.\n",GetLastError());
return;
}
// 计算数据摘要
if(CryptHashData(hHash, text, len, 0) == 0)
{
printf("CryptHashData error:0X%x.\n",GetLastError());
return;
}
if(cert == NULL)
{
printf("pCertContext == NULL:0X%x.\n",GetLastError());
return;
}
//获取公钥句柄
HCRYPTKEY hPubKey;
if(!CryptImportPublicKeyInfo(hProv, cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, &hPubKey))
{
printf("CryptImportPublicKeyInfo error:0X%x.\n",GetLastError());
return;
}
//验证签名
if(!CryptVerifySignature(hHash, signValue, signLen, hPubKey, NULL, 0))
{
printf("CryptVerifySignature error:0X%x.\n",GetLastError());
return;
}
cout << "sign verify successfully" << endl;
相关文章推荐
- CryptoAPI与openssl数字签名与验证交互
- CryptoAPI与openssl数字签名与验证交互
- CryptoAPI与openssl数字签名与验证交互
- OpenSSL学习之使用个人信息数字证书(PFX)进行签名和验证
- OpenSSL学习之使用个人信息数字证书(PFX)进行签名和验证
- OpenSSL学习之使用个人信息数字证书(PFX)进行签名和验证
- CryptAPI 数字签名 与 Openssl 验证签名
- 数字签名验证及加解密中的一些概念
- CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互
- OpenSSL RSA 消息签名与验证
- 没有验证对象的数字签名——解决方案
- openssl与cryptoAPI交互AES加密解密
- Delphi 编写数字签名验证并获取签名信息
- openssl DSA 数字签名与签名验证
- 可再发行平台 SDK:CAPICOM ,对数据进行数字签名、对代码签名、验证数字签名、包封保密数据、对数据进行散列处理、加密及解密数据的SDK
- 调用OpenSSL实现数字签名功能例程(二)
- 公钥加密 私钥解密,私钥数字签名 公钥验证
- 数字签名(代码签名)流程和数字签名的验证
- openssl与cryptoAPI交互AES加密解密
- 用openssl创建签名数字证书:创建CA