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;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值