前段时间将系统的RSA算法全部升级为SM2国密算法,密码机和UKey硬件设备大都同时支持RSA和SM2算法,只是应用系统的加解密签名验证需要修改,这个更改底层调用的加密动态库来,原来RSA用的对称加密算法DES(AES)和摘要MD5(SHA1)也相应改变,分别对应SM1、SM3算法,SM1算法基于硬件实现,SM2、SM3算法已公开。
SM2签名验证算法
SM2签名同样也是需要先摘要原文数据,即先使用SM3密码杂凑算法计算出32byte摘要。SM3需要摘要签名方ID(默认1234567812345678)、曲线参数a,b,Gx,Gy、共钥坐标(x,y)计算出Z值,然后再杂凑原文得出摘要数据。这个地方要注意曲线参数和坐标点都是32byte,在转换为BigInteger大数计算转成字节流时要去掉空补位,否则可能会出现摘要计算不正确的问题。SM2签名实现如下:
SM2签名
publicstaticBigInteger[] Sm2Sign(byte[] md, AsymmetricCipherKeyPair keypair)
...{
SM3Digest sm3=newSM3Digest();
ECPublicKeyParameters ecpub=(ECPublicKeyParameters)keypair.Public;
byte[] z=SM2CryptoServiceProvider.Sm2GetZ(Encoding.Default.GetBytes(SM2CryptoServiceProvider.userId), ecpub.Q);
sm3.BlockUpdate(z,0, z.Length);
byte[] p=md;
sm3.BlockUpdate(p,0, p.Length);
byte[] hashData=newbyte[32];
sm3.DoFinal(hashData,0);
//e
BigInteger e=newBigInteger(1, hashData);
//k
BigInteger k=null;
ECPoint kp=null;
BigInteger r=null;
BigInteger s=null;
BigInteger userD=null;
do
...{
do
...{
ECPrivateKeyParameters ecpriv=(ECPrivateKeyParameters)keypair.Private;
k=ecpriv.D;
kp=ecpub.Q;
userD=ecpriv.D;
//r
r=e.Add(kp.X.ToBigInteger());
r=r.Mod(ecc_n);
}
while(r.Equals(BigInteger.Zero)||r.Add(k).Equals(ecc_n));