二簡單介紹了一下理論,三來簡單說下sm2簽名的實現(xiàn),
首先因為openssl太復雜沒搞懂,就去看gmssl的代碼,gmssl的密鑰結構體很簡單,長這個樣子:
typedef struct {
SM2_POINT public_key;
uint8_t private_key[32];
} SM2_KEY;
typedef struct {
uint8_t x[32];
uint8_t y[32];
} SM2_POINT;
很明顯公鑰是一個點由xy兩個坐標組成,私鑰是一個長串。
sm2簽名過程可以大體上分成三步,生成公私鑰——(交換密鑰)——使用私鑰進行簽名——使用公鑰驗簽。
在gmssl中直接使用sm2_key_generate(&sm2_key)函數(shù),生成密鑰并將密鑰置入結構體中,或者直接使用命令生成密鑰也可以。
獲取到密鑰之后就對原報文進行簽名,具體流程是:
原報文通過sm3算法(沒錯,sm2簽名用了sm3算法)生成雜湊數(shù)據(jù)(也就是e值,e值好像是個通用的叫法?)(也叫做摘要),再將雜湊數(shù)據(jù)傳遞到簽名函數(shù)中,通過私鑰進行簽名得到簽名串。
為什么突然出現(xiàn)sm3呢?這里還需要解釋sm3是什么東西,sm3是一種密碼散列函數(shù)標準,他的特點是,將原數(shù)據(jù)不可逆的生成一串256位長度數(shù)據(jù)。這樣簽名起來就變得很簡單。
具體實現(xiàn)如下:
int sm2_sign_pre(SM2_KEY *sm2_key,
unsigned char *msg,
unsigned char *dgst,
unsigned char *sig,
size_t *siglen ) {
int ret = 0;
sm3_digest(msg, strlen((char*)msg), dgst);
/* sm2_key_generate(&sm2_key); 生成私鑰key和公鑰*/
if ((ret = sm2_sign(sm2_key, dgst, sig, siglen)) != 1) {
fprintf(stderr, "signature failed\n");
}
else {
printf("signature success\n");
}
return ret;
}
而驗簽是當報文收到之后,對報文再次進行摘要(sm3生成雜湊數(shù)據(jù)),而簽名串則拿去用公鑰去解密,解密結果如果報文沒有被篡改,那么將是相同的,驗簽通過,如果原報文經(jīng)過篡改,那么sm3生成雜湊數(shù)據(jù)會變化,以至于對比結果不相同,驗簽無法通過文章來源:http://www.zghlxwxcb.cn/news/detail-800871.html
代碼如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-800871.html
int sm2_verify_pre( SM2_KEY *pub_key,
unsigned char* msg,
unsigned char *dgst,
unsigned char *sig,
size_t siglen
) {
int ret;
sm3_digest(msg, strlen((char*)msg), dgst);
if ((ret = sm2_verify(pub_key, dgst, sig, siglen)) != 1) {
return ret;
}
else {
return 0;
}
}
到了這里,關于sm2簽名與sm4加密(三)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!