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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

SHA1WithRSA签名使用openssl 实现

發(fā)布時間:2024/1/8 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SHA1WithRSA签名使用openssl 实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引言:
2017年就要到了,想想自己使用阿里云搭的博客 眼看就要到期了。 雖說沒寫幾遍有質(zhì)量的文章吧,但是放其不管也于心不忍。這幾天就琢磨著把幾遍有內(nèi)容的轉(zhuǎn)到博客中。在尋求著落點的時候發(fā)現(xiàn)Markdown??戳薈SDN中Markdown的范文,再看看自己曾經(jīng)寫的文章。只能呵呵了
想著就借此機會學習一下Markdown的話語。


最近一個項目對接。要使用SHA1WithRSA簽名驗簽。
之前接觸過DES、3DES、 AES、 SHA1、 MD5、RSA 看這加密想當然的覺得是就是先對數(shù)據(jù)做個SHA1摘要再做個RSA加密嘛,簡單不是。
man 了一下 openssl 關(guān)于RSA加解密。霹靂啪啦幾個小時就把 理解的“SHA1WithRSA”實現(xiàn)了。
但是測試時對方就是驗簽不過。
后面還是問廣大的網(wǎng)絡(luò)。才讓我得了解自己的無知。
這不也有人和犯一樣的錯 哈哈

簡單閱讀一下就能大概知道實際上可以通過openssl的RSA_sign實現(xiàn)
來看一下RSA_sign

#include <openssl/rsa.h>int RSA_sign(int type, const unsigned char *m, unsigned int m_len,unsigned char *sigret, unsigned int *siglen, RSA *rsa);int RSA_verify(int type, const unsigned char *m, unsigned int m_len,unsigned char *sigbuf, unsigned int siglen, RSA *rsa);

DESCRIPTION
RSA_sign() signs the message digest m of size m_len using the private key rsa as specified in PKCS #1 v2.0. It stores the signature in sigret and the signature size in siglen. sigret must point to RSA_size(rsa) bytes of memory. Note that PKCS #1 adds meta-data, placing limits on the size of the key that can be used. See RSA_private_encrypt for lower-level operations.
type denotes the message digest algorithm that was used to generate m. If type is NID_md5_sha1, an SSL signature (MD5 and SHA1 message digests with PKCS #1 padding and no algorithm identifier) is created.
RSA_verify() verifies that the signature sigbuf of size siglen matches a given message digest m of size m_len. type denotes the message digest algorithm that was used to generate the signature. rsais the signer’s public key.
RETURN VALUES
RSA_sign() returns 1 on success. RSA_verify() returns 1 on successful verification.

簡單看看,其實RSA_sing()函數(shù)第一為送NID_sha1

通過這篇文章知道需要簽名的是SHA1摘要而非所有報文。所以要先對明文數(shù)據(jù)做SHA1。再調(diào)用 RSA_sign()簽名。

結(jié)論:

對openSSL源碼一知半解的我,竟把RSA加密|解密和RSA簽名|驗證混淆。
最后 私鑰加密 ≠ 簽名

20170519更新
這幾天看了下這文章閱讀人數(shù)相比還挺多的??臻e之余就把整理下自己以前寫的test程序提供給大家參考下。

秘鑰對是我是使用openssl命令生產(chǎn)的給出的參考如下。另外秘鑰文件格式有很多種,請注意。
生產(chǎn)私鑰

openssl genrsa -out userkey.pem 1024

從私鑰中導出公鑰

openssl rsa in userkey.pem -pubout -out userpub.key

簽名測試代碼

#include <string.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/err.h>RSA* getPrivateKey(char* in_szKeyPath) {FILE *fp = NULL; char szKeyPath[1024];RSA *priRsa = NULL, *pubRsa = NULL, *pOut = NULL;memset(szKeyPath, 0 ,sizeof(szKeyPath));if(256 < strlen(in_szKeyPath))strncpy(szKeyPath, in_szKeyPath, 256);elsestrncpy(szKeyPath, in_szKeyPath, strlen(in_szKeyPath));printf("密鑰文件路徑[%s]", szKeyPath);/* 打開密鑰文件 */if(NULL == (fp = fopen(szKeyPath, "rb"))){printf( "打開密鑰文件[%s]出錯", szKeyPath);return NULL;}/* 獲取私密鑰 */if(NULL == (priRsa = PEM_read_RSAPrivateKey(fp, &priRsa, NULL,NULL))){printf( "讀出私鑰內(nèi)容出錯\n");fclose(fp);return NULL;}fclose(fp);printf("提取私鑰\n");pOut = priRsa;return pOut; }RSA* getPublicKey(char* in_szKeyPath) {FILE *fp = NULL; char szKeyPath[1024];RSA *priRsa = NULL, *pubRsa = NULL, *pOut = NULL;memset(szKeyPath, 0 ,sizeof(szKeyPath));if(256 < strlen(in_szKeyPath))strncpy(szKeyPath, in_szKeyPath, 256);elsestrncpy(szKeyPath, in_szKeyPath, strlen(in_szKeyPath));printf("密鑰文件路徑[%s]", szKeyPath);/* 打開密鑰文件 */if(NULL == (fp = fopen(szKeyPath, "rb"))){printf( "打開密鑰文件[%s]出錯", szKeyPath);return NULL;}/* 獲取公密鑰 */if(NULL == (priRsa = PEM_read_RSA_PUBKEY(fp, &priRsa, NULL,NULL))){printf("讀出私鑰內(nèi)容出錯\n");fclose(fp);return NULL;}fclose(fp);printf("提取公鑰\n");pOut = priRsa;return pOut; }int main(void) {int flen,rsa_len, ienLen, iRet;RSA *prsa = NULL;char szEnData[]="orderId=01010500201502000004reqTime=20150205012727ext=20151120ext2=1";char szTmp[10240], szTmp1[10240];if(NULL == (prsa = getPrivateKey("userkey.pem"))){RSA_free(prsa);printf("獲取私鑰失敗\n");return -1;}// RSA_print_fp(stdout, prsa, 11);flen = strlen(szEnData);printf("待簽名數(shù)據(jù):[%s]\n", szEnData);memset(szTmp, 0, sizeof(szTmp));memset(szTmp1, 0, sizeof(szTmp1));// 對待簽名數(shù)據(jù)做SHA1摘要SHA1(szEnData, flen, szTmp);//使用私鑰對SHA1摘要做簽名ienLen = RSA_sign(NID_sha1, (unsigned char *)szTmp, 20, (unsigned char*)szTmp1, &iRet, prsa);if(ienLen != 1 ){printf("簽名失敗\n");RSA_free(prsa);return -1;}RSA_free(prsa);printf("簽名成功\n");//簽名串szTmp1二進制數(shù)據(jù)需要轉(zhuǎn)成base64編碼//mac=base64encode(szTmp1)這是偽碼,生產(chǎn)MAC值,給對方去校驗//驗證簽名//驗證簽名的是需要獲取MAC值,明文簽名數(shù)據(jù),對“明文簽名數(shù)據(jù)”做SHA1,獲得摘要。在對MAC做basedecode(mac),然后調(diào)用函數(shù)驗證簽名if(NULL == (prsa = getPublicKey("userpub.key"))){RSA_free(prsa);printf("獲取私鑰失敗\n");return -1;}flen = strlen(szEnData);printf("待簽名數(shù)據(jù):[%s]\n", szEnData);//簽名數(shù)據(jù) 和 mac 因該是由通信報文中獲得,這里演示直接用使用同一變量memset(szTmp, 0, sizeof(szTmp));memset(szTmp1, 0, sizeof(szTmp1));// 對待簽名數(shù)據(jù)做SHA1摘要SHA1(szEnData, flen, szTmp);ienLen = RSA_verify(NID_sha1, (unsigned char *)szTmp, 20, (unsigned char*)szTmp1, iRet, prsa);if(ienLen != 1 ){printf("簽名不合法\n");RSA_free(prsa);return -1;}elseprintf("驗簽成功\n");RSA_free(prsa);return 0; }

源碼和秘鑰文件資源

總結(jié)

以上是生活随笔為你收集整理的SHA1WithRSA签名使用openssl 实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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