当前位置: 首页> 健康> 母婴 > 遵义市播州区疫情最新消息_网络运维工程师培训_举例一个成功的网络营销案例_厦门网站建设公司哪家好

遵义市播州区疫情最新消息_网络运维工程师培训_举例一个成功的网络营销案例_厦门网站建设公司哪家好

时间:2025/7/20 23:26:58来源:https://blog.csdn.net/qq_29709589/article/details/145882990 浏览次数:0次
遵义市播州区疫情最新消息_网络运维工程师培训_举例一个成功的网络营销案例_厦门网站建设公司哪家好

前言

SM2是中国国家密码管理局发布的椭圆曲线公钥密码算法标准(GB/T 32918),属于国密算法体系。与RSA和ECDSA相比,SM2在相同安全强度下密钥更短、计算效率更高。本文将介绍如何在Java中实现SM2的密钥生成数字签名验签加密解密功能。

一、结果验证

1.代码运行结果

1.1 不带id签名验签代码运行结果

在这里插入图片描述

1.2 带id签名验签代码运行结果

在这里插入图片描述

1.3 SM2加密解密代码运行结果

在这里插入图片描述

2.工具验证结果

2.1 不带id签名验签工具运行结果

在这里插入图片描述

2.2 带id签名验签工具运行结果

在这里插入图片描述

2.3 SM2加密解密工具运行结果

在这里插入图片描述

二、SM2签名原理

SM2签名过程的核心是利用私钥对消息进行签名,生成签名值 (r, s)。具体步骤如下:

  1. 计算消息的哈希值
    使用SM3哈希算法对消息 M 进行哈希处理,得到哈希值 e

  2. 生成随机数
    选择一个随机数 k,满足 1 < k < n,其中 n 是椭圆曲线的阶。

  3. 计算椭圆曲线点
    使用随机数 k 计算椭圆曲线上的点 Q = kG,其中 G 是椭圆曲线的基点。取点 Qx 坐标 x1

  4. 计算签名值 r
    计算 r = (e + x1) mod n。如果 r = 0r + k = n,则重新选择随机数 k

  5. 计算签名值 s
    计算 s = (1 + d)^{-1} * (k - r * d) mod n,其中 d 是私钥。

  6. 输出签名结果
    签名结果为 (r, s),通常以字节数组的形式存储和传输。

三、SM2验签原理

SM2验签过程的核心是利用公钥验证签名的有效性。具体步骤如下:

  1. 计算消息的哈希值
    使用SM3哈希算法对消息 M 进行哈希处理,得到哈希值 e

  2. 计算值 t
    计算 t = (r + s) mod n,其中 rs 是签名值。

  3. 计算椭圆曲线点
    计算点 R = sG + tP,其中 G 是椭圆曲线的基点,P 是签名者的公钥。取点 Rx 坐标 x1

  4. 验证签名
    验证等式 r = (e + x1) mod n 是否成立。如果成立,则签名有效;否则,签名无效。

四、SM2签名与验签的Java实现

1. 添加依赖

pom.xml中添加Bouncy Castle依赖:

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

2. 生成密钥对

/*** 生成SM2密钥对。** @return 生成的密钥对(包含公钥和私钥)* @throws Exception 如果密钥生成过程中发生错误*/public static KeyPair generateKeyPair() throws Exception {// 添加Bouncy Castle安全提供者Security.addProvider(new BouncyCastleProvider());// 获取SM2椭圆曲线参数(使用sm2p256v1曲线)ECParameterSpec sm2Spec = ECNamedCurveTable.getParameterSpec("sm2p256v1");// 创建EC密钥对生成器实例KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");// 初始化密钥对生成器,指定椭圆曲线参数和随机数生成器kpg.initialize(sm2Spec, new SecureRandom());// 生成密钥对并返回return kpg.generateKeyPair();}

3. 签名不带ID

 /*** 使用SM2算法进行签名(不使用用户ID)。** @param data       待签名的数据(字节数组)* @param privateKey 签名使用的私钥* @return 签名结果(字节数组)* @throws Exception 如果签名过程中发生错误*/public static String signNoId(byte[] data, PrivateKey privateKey) throws Exception {// 创建SM2签名实例,指定使用SM3哈希算法Signature signature = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);// 初始化签名器,使用私钥signature.initSign(privateKey);// 更新待签名的数据signature.update(data);// 生成签名byte[] signatureBytes = signature.sign();// 解析 DER 编码的签名结果ASN1Sequence sequence = ASN1Sequence.getInstance(signatureBytes);BigInteger r = ASN1Integer.getInstance(sequence.getObjectAt(0)).getValue();BigInteger s = ASN1Integer.getInstance(sequence.getObjectAt(1)).getValue();// 打印 r 和 s 的值System.out.println("r 的十六进制值: " + r.toString(16));System.out.println("s 的十六进制值: " + s.toString(16));// 将 
关键字:遵义市播州区疫情最新消息_网络运维工程师培训_举例一个成功的网络营销案例_厦门网站建设公司哪家好

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: