JAVA SM2加密的问题有哪些?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
<强> SM2加密的流程强>
SM2使用的椭圆曲线基点记为G,私钥为整数d,公钥为p=dG。,这里K, G为椭圆曲线上的点,d为正整数
选择随机整数K,计算C1=公斤,C4=kP
以点C4的X/Y两坐标为参数,计算一组字节流T,与明文进行异或运算,结果为C2
已C1和明文组合,用SM3算法计算哈希值C3
将C1, C2, C3组合为加密后的密文
这里只要得到C4,便能进行解密,而C4 dkP==kP=kdP=d (kC)=dC1。而C1是密文的一部分,所以有了私钥d便可以进行解密。
这里的p, G, C1, C4是椭圆曲线上的点,点的乘法只具有几何意义上,并非2 x3=6的算术运算。
<强> 1。加密密文的组合强>
加密后的密文,标准为C1 | | C3 | | C2, C3位SM3哈系值,而这个库中结果为C1 | | C2 | | C3。
<强> 2。先导入BigInteger的Java最高位为1时编码错误强>
Java中,BigInteger的最高位为1时,toByteArray()得到的字节数组会多一位,在前面多了一个为0的字节,应该是要表示为正数。导致运算结果和其他语言的不一致。
<强> 3。计算T时的差异强>
计算T时,需要用点C4的X坐标和Y坐标组合进行,这个库里直接调用bouncycastle库里,ECPoint类的getEncoded()的方法,得到的结果是在字节流里加了一个字节(0 x4),实际是不需要的,导致计算的字节流T有差异
<强> 4。取点的X/Y坐标时没有正则化强>
java的bouncycastle库里,在椭圆曲线的计算中,使用了X/Y/Z三个坐标,而其他的实现可能是没有Z坐标的,所以调用点的坐标的时候,应该调用规范化()方法正则化后使用,这时Z坐标是1 .
而在这个库中,并没有进行正则化的操作,导致加密结果无法与其他程序进行交互,除非对方也使用的bouncycastle库,可实现方式与其类似。
<强> SM2数字签名算法java实现强>
给出我的SM2数字签名算法代码java实现,所属文件SM2Signer。java
@Override 先导入BigInteger[]公共generateSignature (byte[]消息){ ECDomainParameters ec=key.getParameters (); BigInteger n=ec.getN ();//n阶 ECPoint G=ec.getG ();//基G点 BigInteger r, s;//获取私钥d BigInteger d=((ECPrivateKeyParameters)键).getD (); ECMultiplier basePointMultiplier=createBasePointMultiplier ();//初始化随机数生成器 如果(kCalculator.isDeterministic ()) { kCalculator。init (n、d、消息); 其他}{ kCalculator。init (n,随机); } {//计算年代 BigInteger k; BigInteger e; BigInteger tmp; BigInteger tmp2; {//计算r,参照通用/T 0003.2 -2012 6.1 k=kCalculator.nextK (); ECPoint p=basePointMultiplier。乘(G、k) .normalize (); e=org.bouncycastle.util.BigIntegers.fromUnsignedByteArray(消息);//r=(e + x) mod n 阀门.toBigInteger r=p.getAffineXCoord () () (e) mod (n)名; },(斜边(0)| | r.add (k) .equals (n));//tmp=(1 + d) .inverse tmp=d.add(一).modInverse (n);//tmp2=k - r * d tmp2=k.subtract (r.multiply (d)); s=tmp.multiply (tmp2) mod (n)名; },(s.equals (0)); 先导入BigInteger[]返回新{(r, s}; }
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。