生活随笔
收集整理的這篇文章主要介紹了
CryptoAPI与openssl数字签名与验证交互
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://blog.csdn.net/zhouyuqwert/article/details/7467296
昨天寫過了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))???????{????????????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))???????{????????????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);????}??
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)??{?????????? ??????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,??????????????????????????????????0,??????????????????????????????????????&hHash))??????????????????????????{??????????????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;??}??
與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的CryptoAPI与openssl数字签名与验证交互的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。