国密库研究备份

近一年有了两次使用国密来签名的需求,还是备份一下了解到的知识吧。避免又要google一遍,虽然我是面向google编程

文档备份

SM3WITHSM2

SM3WITHSM2与SHA256WITHRSA过程类似,最大的区别在于对消息的Hash值计算,后者是SHA256(MSG)(太天真了),前者是SM3(Z+MSG),多了一个Z值。(还是太天真了),SHA256WITHRSA的算法公式: RSA.decrypt(PKCS1Padding(DER(OID, SHA256)), PrivateKey),SM3WITHSM2的是:SM2.sign(SM3(Z+MSG),PrivateKey)。

Z值计算

Z = Hash256(Len(ID) + ID + a + b + xG + yG + xA + yA

Hash256是Hash结果为256位的Hash函数,一般用的是SM3。

长度

SM2参数的域为256bit的整数,公钥(xA,yA)是在这范围内的点,私钥d是这个域上随机的一个值,签名结果(r,s)是在这范围内的点,所以私钥长度为64Byte,其他的长度为256bit+256bit,即64Byte。

SM3WITHSM2变种

有些公司对SM2签名的实现是少了计算Z值的,直接就是SM3(MSG),当签名验证不通过的时候,可以往这方面想。

国密库

  • 纯JAVA实现:bcprov-jdk15on(编写本文章时最新版本是1.59,只支持标准SM3WITHSM2,不能改其他Hash函数)
  • C实现带JNI:GmSSL(可以使用不同的Hash函数)
  • C实现:OpenSSL(应该是1.1.1会有正式支持,编写本文章时是1.1.1_pre)