0


sm2签名与sm4加密(三)

二简单介绍了一下理论,三来简单说下sm2签名的实现,

首先因为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)函数,生成密钥并将密钥置入结构体中,或者直接使用命令生成密钥也可以。

获取到密钥之后就对原报文进行签名,具体流程是:

原报文通过sm3算法(没错,sm2签名用了sm3算法)生成杂凑数据(也就是e值,e值好像是个通用的叫法?)(也叫做摘要),再将杂凑数据传递到签名函数中,通过私钥进行签名得到签名串。

为什么突然出现sm3呢?这里还需要解释sm3是什么东西,sm3是一种密码散列函数标准,他的特点是,将原数据不可逆的生成一串256位长度数据。这样签名起来就变得很简单。

具体实现如下:

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生成杂凑数据),而签名串则拿去用公钥去解密,解密结果如果报文没有被篡改,那么将是相同的,验签通过,如果原报文经过篡改,那么sm3生成杂凑数据会变化,以至于对比结果不相同,验签无法通过

代码如下:

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;
    }
}
标签: 安全 c语言 算法

本文转载自: https://blog.csdn.net/2301_76249656/article/details/130014704
版权归原作者 glodrar 所有, 如有侵权,请联系我们删除。

“sm2签名与sm4加密(三)”的评论:

还没有评论