/** * 私钥签名 * 使用SM3进行对明文数据计算一个摘要值 * @param privatekey 私钥 * @param sourceData 明文数据 * @return 签名后的值 * @throws Exception */ public static SM2SignVO Sign2SM2(byte[] privatekey, byte[] sourceData) { SM2SignVO sm2SignVO = new SM2SignVO(); sm2SignVO.setSm2_type("sign"); var factory = SM2CryptoServiceProvider.Instance; BigInteger userD = new BigInteger(privatekey); //System.out.println("userD:"+userD.toString(16)); sm2SignVO.setSm2_userd(userD.ToByteArray().ToHexString()); ECPoint userKey = factory.ecc_point_g.Multiply(userD); //System.out.println("椭圆曲线点X: "+ userKey.getXCoord().toBigInteger().toString(16)); //System.out.println("椭圆曲线点Y: "+ userKey.getYCoord().toBigInteger().toString(16)); SM3Digest sm3Digest = new SM3Digest(); byte[] z = factory.Sm2GetZ(USER_ID.GetBytes(), userKey); //System.out.println("SM3摘要Z: " + Util.getHexString(z)); //System.out.println("被加密数据的16进制: " + Util.getHexString(sourceData)); sm2SignVO.setSm3_z(z.ToHexString()); sm2SignVO.setSign_express(sourceData.ToHexString()); sm3Digest.update(z, 0, z.Length); sm3Digest.update(sourceData, 0, sourceData.Length); byte[] md = new byte[32]; sm3Digest.doFinal(md, 0); //System.out.println("SM3摘要值: " + Util.getHexString(md)); sm2SignVO.setSm3_digest(md.ToHexString()); SM2Result sm2Result = new SM2Result(); factory.sm2Sign(md, userD, userKey, sm2Result); //System.out.println("r: " + sm2Result.r.toString(16)); //System.out.println("s: " + sm2Result.s.toString(16)); sm2SignVO.setSign_r(sm2Result.r.ToByteArray().ToHexString()); sm2SignVO.setSign_s(sm2Result.s.ToByteArray().ToHexString()); var d_r = new DerInteger(sm2Result.r); var d_s = new DerInteger(sm2Result.s); var v2 = new Asn1EncodableVector(); v2.Add(d_r); v2.Add(d_s); var sign = new DerSequence(v2); String result = sign.GetEncoded().ByteArrayToHex(); sm2SignVO.setSm2_sign(result); return(sm2SignVO); }
//========================================================================================================= /// <summary> /// 签名相关值计算 /// </summary> /// <param name="md"></param> /// <param name="userD"></param> /// <param name="userKey"></param> /// <param name="sm2Result"></param> public void sm2Sign(byte[] md, BigInteger userD, ECPoint userKey, SM2Result sm2Result) { BigInteger e = new BigInteger(1, md); BigInteger k = null; ECPoint kp = null; BigInteger r = null; BigInteger s = null; do { do { // 正式环境 AsymmetricCipherKeyPair keypair = ecc_key_pair_generator.GenerateKeyPair(); ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)keypair.Private; ECPublicKeyParameters ecpub = (ECPublicKeyParameters)keypair.Public; k = ecpriv.D; kp = ecpub.Q; //System.out.println("BigInteger:" + k + "\nECPoint:" + kp); //System.out.println("计算曲线点X1: "+ kp.getXCoord().toBigInteger().toString(16)); //System.out.println("计算曲线点Y1: "+ kp.getYCoord().toBigInteger().toString(16)); //System.out.println(""); // r r = e.Add(kp.XCoord.ToBigInteger()); r = r.Mod(this.ecc_n); } while (r.Equals(BigInteger.Zero) || r.Add(k).Equals(this.ecc_n) || r.ToByteArray().ToHexString().Length != 64); // (1 + dA)~-1 BigInteger da_1 = userD.Add(BigInteger.One); da_1 = da_1.ModInverse(this.ecc_n); // s s = r.Multiply(userD); s = k.Subtract(s).Mod(this.ecc_n); s = da_1.Multiply(s).Mod(this.ecc_n); } while (s.Equals(BigInteger.Zero) || (s.ToByteArray().ToHexString().Length != 64)); sm2Result.r = r; sm2Result.s = s; }
/// <summary> /// 验证签名 /// </summary> /// <param name="publicKey">公钥信息</param> /// <param name="sourceData">密文信息</param> /// <param name="signData">签名信息</param> /// <returns>验签的对象 包含了相关参数和验签结果</returns> public static SM2SignVO VerifySignSM2(byte[] publicKey, byte[] sourceData, byte[] signData) { try { byte[] formatedPubKey; SM2SignVO verifyVo = new SM2SignVO(); verifyVo.setSm2_type("verify"); if (publicKey.Length == 64) { // 添加一字节标识,用于ECPoint解析 formatedPubKey = new byte[65]; formatedPubKey[0] = 0x04; System.Array.Copy(publicKey, 0, formatedPubKey, 1, publicKey.Length); } else { formatedPubKey = publicKey; } var factory = SM2CryptoServiceProvider.Instance; ECPoint userKey = factory.ecc_curve.DecodePoint(formatedPubKey); SM3Digest sm3Digest = new SM3Digest(); byte[] z = factory.Sm2GetZ(USER_ID.GetBytes(), userKey); //System.out.println("SM3摘要Z: " + Util.getHexString(z)); verifyVo.setSm3_z(z.ToHexString()); sm3Digest.update(z, 0, z.Length); sm3Digest.update(sourceData, 0, sourceData.Length); byte[] md = new byte[32]; sm3Digest.doFinal(md, 0); //System.out.println("SM3摘要值: " + Util.getHexString(md)); verifyVo.setSm3_digest(md.ToHexString()); var bis = new MemoryStream(signData); var dis = new Asn1InputStream(bis); SM2Result sm2Result = null; var derObj = dis.ReadObject(); var e = ((Asn1Sequence)derObj).GetEnumerator(); e.MoveNext(); BigInteger r = ((DerInteger)e.Current).Value; e.MoveNext(); BigInteger s = ((DerInteger)e.Current).Value; sm2Result = new SM2Result(); sm2Result.r = r; sm2Result.s = s; //System.out.println("vr: " + sm2Result.r.toString(16)); //System.out.println("vs: " + sm2Result.s.toString(16)); verifyVo.setVerify_r(sm2Result.r.ToByteArray().ToHexString()); verifyVo.setVerify_s(sm2Result.s.ToByteArray().ToHexString()); factory.sm2Verify(md, userKey, sm2Result.r, sm2Result.s, sm2Result); var verifyFlag = sm2Result.r.Equals(sm2Result.R); verifyVo.setVerify(verifyFlag); return(verifyVo); } catch (ArgumentException e) { //throw e; return(null); } catch (Exception e) { //throw e; //e.printStackTrace(); return(null); } }
/// <summary> /// 验签 /// </summary> /// <param name="md">sm3摘要</param> /// <param name="userKey">根据公钥decode一个ecpoint对象</param> /// <param name="r">没有特殊含义</param> /// <param name="s">没有特殊含义</param> /// <param name="sm2Result">sm2Result 接收参数的对象</param> public void sm2Verify(byte[] md, ECPoint userKey, BigInteger r, BigInteger s, SM2Result sm2Result) { sm2Result.R = null; BigInteger e = new BigInteger(1, md); BigInteger t = r.Add(s).Mod(this.ecc_n); if (t.Equals(BigInteger.Zero)) { return; } else { ECPoint x1y1 = ecc_point_g.Multiply(sm2Result.s); //System.out.println("计算曲线点X0: "+ x1y1.normalize().getXCoord().toBigInteger().toString(16)); //System.out.println("计算曲线点Y0: "+ x1y1.normalize().getYCoord().toBigInteger().toString(16)); //System.out.println(""); x1y1 = x1y1.Add(userKey.Multiply(t)); //System.out.println("计算曲线点X1: "+ x1y1.normalize().getXCoord().toBigInteger().toString(16)); //System.out.println("计算曲线点Y1: "+ x1y1.normalize().getYCoord().toBigInteger().toString(16)); //System.out.println(""); sm2Result.R = e.Add(x1y1.Normalize().XCoord.ToBigInteger()).Mod(this.ecc_n); //System.out.println("R: " + sm2Result.R.toString(16)); return; } }