Java SM2 国密算法使用

Java SM2 国密算法使用


这里需要引入对应的依赖:

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

生成密钥对

BouncyCastleProvider provider = new BouncyCastleProvider();
// 获取椭圆曲线相关生成参数规格
ECGenParameterSpec genParameterSpec = new ECGenParameterSpec("sm2p256v1");
// 获取一个椭圆曲线类型的密钥对生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", provider);
// 使用SM2的算法区域初始化密钥生成器
keyPairGenerator.initialize(genParameterSpec, new SecureRandom());

// 生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
BCECPrivateKey privateKey = (BCECPrivateKey) keyPair.getPrivate();
BCECPublicKey publicKey = (BCECPublicKey) keyPair.getPublic();

// 拿到32字节的私钥HEX
System.out.println("Private Key: " + privateKey.getD().toString(16));

// true  代表压缩密钥,以02、03开头,长度为33字节
// false 代表未压缩,以04开头,长度为65字节
System.out.println("Public Key: " + Hex.encode(publicKey.getQ().getEncoded(true)));

加载HEX密钥对字符串

String prvKey = "私钥HEX字符串", pubKey = "公钥HEX字符串";
// 获取SM2相关参数
X9ECParameters parameters = GMNamedCurves.getByName("sm2p256v1");
// 椭圆曲线参数规格
ECParameterSpec ecParameterSpec = new ECParameterSpec(parameters.getCurve(), parameters.getG(), parameters.getN(), parameters.getH());
// 将公钥HEX字符串转换为椭圆曲线对应的点
ECPoint ecPoint = parameters.getCurve().decodePoint(Hex.decode(pubKey));
// 将私钥HEX字符串转换为X值
BigInteger bigInteger = new BigInteger(prvKey, 16);
// 获取椭圆曲线KEY生成器
KeyFactory keyFactory = KeyFactory.getInstance("EC", provider);
// 将X值转为私钥KEY对象
BCECPrivateKey privateKey = (BCECPrivateKey) keyFactory.generatePrivate(new ECPrivateKeySpec(bigInteger, ecParameterSpec));
// 将椭圆曲线点转为公钥KEY对象
BCECPublicKey publicKey = (BCECPublicKey) keyFactory.generatePublic(new ECPublicKeySpec(ecPoint, ecParameterSpec));

签名和验签

byte[] bytes = "Hello World".getBytes(), signBytes;
// 创建签名对象
Signature signature = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), provider);
// 初始化为签名状态
signature.initSign(privateKey);
// 传入签名字节
signature.update(bytes);
// 返回签名字节
System.out.println(Hex.encode(signBytes = signature.sign()));
// 初始化为验签状态
signature.initVerify(publicKey);
// 传入签名字节
signature.update(bytes);
// 返回验签结果
System.out.println(signature.verify(signBytes));

加解密

注:这里加解密与RSA有所区别,加密要用公钥加密,用私钥解密

String word = "你好世界";
// 获取SM2加密器
Cipher cipher = Cipher.getInstance("SM2", provider);
// 初始化为加密模式
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// 加密并编码为base64格式
word = Base64.getEncoder().encodeToString(cipher.doFinal(word.getBytes()));
System.out.println("密文:" + word);
// 初始化为解密模式
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// 解密
word = new String(cipher.doFinal(Base64.getDecoder().decode(word)));
System.out.println("解密:" + word);

以上就是全部内容。

  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,关于Java基于SM2国密算法传输数据,需要先引入Bouncy Castle库,它是一个提供了许多加密算法支持的开源库。接下来,我们需要使用SM2算法进行加密和解密。 下面是使用SM2算法进行加密和解密的基本步骤: 1. 生成SM2密钥对,包括公钥和私钥。 2. 使用公钥进行加密,将明文数据进行加密,得到密文。 3. 使用私钥进行解密,将密文进行解密,得到明文数据。 下面是一个简单的Java代码示例,演示了如何使用SM2算法进行加密和解密: ``` import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import java.security.Security; public class SM2EncryptionDemo { public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); // 生成SM2密钥对 ECKeyPairGenerator generator = new ECKeyPairGenerator(); generator.init(new ParametersWithRandom(SM2Util.getSM2ParameterSpec(), new SecureRandom())); AsymmetricCipherKeyPair keyPair = generator.generateKeyPair(); ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters) keyPair.getPrivate(); ECPublicKeyParameters publicKey = (ECPublicKeyParameters) keyPair.getPublic(); // 明文数据 String plainText = "Hello, world!"; // 使用公钥进行加密 byte[] cipherText = SM2Util.encrypt(publicKey, plainText.getBytes()); // 使用私钥进行解密 byte[] decryptedData = SM2Util.decrypt(privateKey, cipherText); String decryptedText = new String(decryptedData); System.out.println("明文数据: " + plainText); System.out.println("加密后的数据:" + Hex.toHexString(cipherText)); System.out.println("解密后的数据:" + decryptedText); } } ``` 需要注意的是,SM2算法需要使用国密规范的参数,可以使用Bouncy Castle库中提供的SM2Util类来获取SM2相关参数。具体实现细节可以参考相关文档和API。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值