SM2数字签名结果的分析,本应64字节,为啥有工具显示70字节、71字节、72个字节三种结果

SM2数字签名结果的分析,本应64字节,为啥有工具显示70字节、71字节、72个字节三种结果

由于编写了《商用密码与安全性评估》书籍,最近收到不少朋友的来信,询问为啥BC库的签名结果是三种字节长度?另一个问题就是密码测评师需要了解编程和代码么 ?

我先回答第二个问题,密码测评师是需要了解代码的,精通程序的测评师才能有利的分析密码算法实现的正确性和有效性,才能明白是不是真正实现了相应的算法而不是欺骗。

关于第一个问题,我们来分析下原因:

 

用工具和BC库为啥签名结果长度有70,71,72 三个结果呢?

把其中的一个结果拷贝下来分析:

3045022053158C29EA739622E0109971E6BBC89C068A9C647D190FA08D02D0EA8EE1AEE1022100C8E815C0A688D910E1890C29C639CB5BF53F2464768B132A5DCB9CF68CFC3D7B

把它转换成一个二进制文件

用ASN.1工具解析器打开该二进制文件:

 

可以看到有两个大整数组成,这应该就是签名结果的 R,S ,因此出现如此长度的签名结果是因为DER编码所致。

为啥后面是33字节? 因为填充了一个00字节,为啥填充零字节呢?看后面的整数的第一个字节C8 ,转换成二进制是11001000 ,根据整数的特性这个数就是负数了,而这里SM2用到的r,s都是无符号整数,所以要进行编码增加00000000的整数前缀,使得它是个正整数。

因此当r,s的最高位都是0位时,不需要填充,它就是等于增加了六个字节的标志字节,累计70字节;当其中一个最高位是1位时,需要填充00,它就是等于增加了七个字节的标志字节,累计71字节;当两个最高位都是1位时,都需要填充00,它就是等于增加了八个字节的标志字节,累计72字节

结合BC库源代码再核实一下是不是DER编码:

 

 

总结:密评中签名结果判断第一个字节应该是30 ,第二个字节如果是44 ,后面肯定有两个0220 ;第二个字节如果是45 ,后面出现一个0220,一个022100 ;第二个字节如果是46 ,后面出现两个022100

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现SM3/SM2数字签名,需要以下步骤: 1. 生成SM2密钥对:包括公钥和私钥。 2. 计算消息的哈希值:使用SM3算法对消息进行哈希计算,并将哈希值表示为一个整数。 3. 对哈希值进行签名:使用私钥对哈希值进行数字签名,生成签名值。 4. 验证签名:使用公钥对签名值进行验证,确保签名的正确性。 以下是具体实现步骤: 1. 生成SM2密钥对: 以Java语言为例,使用Bouncy Castle中的SM2密钥生成器可以轻松生成SM2密钥对: ```java Security.addProvider(new BouncyCastleProvider()); // 生成SM2密钥对 KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME); ECGenParameterSpec ecSpec = new ECGenParameterSpec("sm2p256v1"); kpg.initialize(ecSpec, new SecureRandom()); KeyPair keyPair = kpg.generateKeyPair(); // 获取公钥和私钥 PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate(); ``` 2. 计算消息的哈希值: 使用Bouncy Castle中的SM3消息摘要算法可以轻松计算消息的哈希值: ```java // 计算消息的哈希值 byte[] message = "Hello, world!".getBytes(); byte[] hash = new byte[32]; SM3.Digest sm3 = new SM3.Digest(); sm3.update(message, 0, message.length); sm3.doFinal(hash, 0); ``` 3. 对哈希值进行签名: 使用Bouncy Castle中的SM2数字签名算法可以轻松对哈希值进行签名: ```java // 对哈希值进行签名 Signature signature = Signature.getInstance("SM3withSM2", BouncyCastleProvider.PROVIDER_NAME); signature.initSign(privateKey); signature.update(hash, 0, hash.length); byte[] signatureValue = signature.sign(); ``` 4. 验证签名: 使用Bouncy Castle中的SM2数字签名算法可以轻松验证签名: ```java // 验证签名 Signature signature = Signature.getInstance("SM3withSM2", BouncyCastleProvider.PROVIDER_NAME); signature.initVerify(publicKey); signature.update(hash, 0, hash.length); boolean valid = signature.verify(signatureValue); ``` 以上就是SM3/SM2数字签名实现步骤。需要注意的是,使用SM2算法进行数字签名时,签名值是一个字节数组,而不是一个字符串。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值