您的位置:首页 > 运维架构

CryptoAPI与openssl数字签名与验证交互

2016-04-04 17:14 393 查看
昨天写过了RSA非对称加密解密的交互方式,

其实数字签名也是RSA非对称加密,只不过用私钥加密的,再加上个hash摘要

CryptoAPI与openssl
RSA非对称加密解密(PKCS1 PADDING)交互已经提到关于证书和私钥的数据以及对象获取,这里就不再重复讨论

1.openssl的签名及验证

[cpp] view
plain copy

print?

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
plain copy

print?

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: