java SM2 **生成 签名验签

Before Start

SM2算法使用请参考:《GMT 0009-2012 SM2密码算法使用规范 》


bouncycastle - 1.57版本之后,加入了对 我国的SM2、SM3、SM4算法的支持

Bouncycastle releasenotes

java SM2 **生成 签名验签

Build with Maven

适配JDK 1.5 版本

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.60</version>
</dependency>

QuickStart

Github

**对生成

SM2 非对称算法**对生成。

// 获取SM2 椭圆曲线推荐参数
X9ECParameters ecParameters = GMNamedCurves.getByName("sm2p256v1");
// 构造EC 算法参数
ECNamedCurveParameterSpec sm2Spec = new ECNamedCurveParameterSpec(
        // 设置SM2 算法的 OID
        GMObjectIdentifiers.sm2p256v1.toString()
        // 设置曲线方程
        , ecParameters.getCurve()
        // 椭圆曲线G点
        , ecParameters.getG()
        // 大整数N
        , ecParameters.getN());
// 创建 **对生成器
KeyPairGenerator gen = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());

// 使用SM2的算法区域初始化**生成器
gen.initialize(sm2Spec, new SecureRandom());
// 获取**对
KeyPair keyPair = gen.generateKeyPair();

关于椭圆曲线的推荐参数请参考 IETF draft-shen-sm2-ecdsa-02 #appendix-D

在BC中已经为构造了SM2算法参数,并提供算法OID,请参考:

国密算法OID及意义

国密算法OID 源码

SM2算法推荐参数 源码

签名验签

产生了**对之后,就可以使用JAVA security 提供的一些标准化的接口来完成签名验签操作。

/*
获取公私钥
 */
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

// 生成SM2sign with sm3 签名验签算法实例
Signature signature = Signature.getInstance(
				 GMObjectIdentifiers.sm2sign_with_sm3.toString()
				, new BouncyCastleProvider());

/*
签名
 */
// 签名需要使用私钥,使用私钥 初始化签名实例
signature.initSign(privateKey);
// 签名原文
byte[] plainText = "Hello world".getBytes(StandardCharsets.UTF_8);
// 写入签名原文到算法中
signature.update(plainText);
// 计算签名值
byte[] signatureValue = signature.sign();
System.out.println("signature: \n" + Hex.toHexString(signatureValue));

/*
验签
 */
// 签名需要使用公钥,使用公钥 初始化签名实例
signature.initVerify(publicKey);
// 写入待验签的签名原文到算法中
signature.update(plainText);
// 验签
System.out.println("Signature verify result: " + signature.verify(signatureValue));

你可以在 国密算法OID 中找到需要算法的OID字符串。
如: SM2Sign-with-SM3 1.2.156.10197.1.501