日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2025/3/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CryptoAPI与openssl数字签名与验证交互 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

http://blog.csdn.net/zhouyuqwert/article/details/7467296

昨天寫過了RSA非對稱加密解密的交互方式,

其實數(shù)字簽名也是RSA非對稱加密,只不過用私鑰加密的,再加上個hash摘要

CryptoAPI與openssl RSA非對稱加密解密(PKCS1 PADDING)交互已經(jīng)提到關(guān)于證書和私鑰的數(shù)據(jù)以及對象獲取,這里就不再重復討論


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");????
  • ????}????
  • ????//釋放內(nèi)存?? ??
  • ????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"); } //釋放內(nèi)存 EVP_PKEY_free(evpKey); EVP_MD_CTX_cleanup(&mdctx); }
    2.CryptoAPI的簽名驗證

    依然是私鑰的問題,沒時間再去嘗試導入私鑰,暫且只寫驗證

    因為也是RSA加密,所以同樣要注意字節(jié)排列方式,具體看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;??
  • ????}??
  • ??
  • ????//?創(chuàng)建離散對象???? ??
  • ????HCRYPTHASH?hHash?=?NULL;??????
  • ????if(!CryptCreateHash(??????
  • ????????hProv,????????????????????????//?容器句柄????? ??
  • ????????CALG_MD5,????????????????????//?算法標識???? ??
  • ????????NULL,????????????????????????//?算法使用的Key???? ??
  • ????????0,????????????????????????????//?算法標識???? ??
  • ????????&hHash))????????????????????//?返回的HASH對象???? ??
  • ????{??????
  • ????????printf("CryptCreateHash?error:0X%x.\n",GetLastError());??
  • ????????return;??
  • ????}??????
  • ??????
  • ????//?計算數(shù)據(jù)摘要???? ??
  • ????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位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

    總結(jié)

    以上是生活随笔為你收集整理的CryptoAPI与openssl数字签名与验证交互的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。