加密与安全_ sm-crypto 国密算法sm2、sm3和sm4的Java库

在这里插入图片描述


Pre

加密与安全_三种方式实现基于国密非对称加密算法的加解密和签名验签


sm-crypto

https://github.com/antherd/sm-crypto

国密算法sm2、sm3和sm4的java版。基于js版本进行封装,无缝兼容js版公私钥加解密。

PS: js版:https://github.com/JuneAndGreen/sm-crypto

PS: 小程序版:https://github.com/wechat-miniprogram/sm-crypto

如何使用

如何引入依赖

如果需要使用已发布的版本,在dependencies中添加如下依赖

<dependency>
    <groupId>com.antherd</groupId>
    <artifactId>sm-crypto</artifactId>
    <version>0.3.2.1</version>
</dependency>

sm2

获取密钥对

Keypair keypair = Sm2.generateKeyPairHex();
String privateKey = keypair.getPrivateKey(); // 公钥
String publicKey = keypair.getPublicKey(); // 私钥

加密解密

// cipherMode 1 - C1C3C2,0 - C1C2C3,默认为1
String encryptData = Sm2.doEncrypt(msg, publicKey); // 加密结果
String decryptData = Sm2.doDecrypt(encryptData, privateKey); // 解密结果

签名验签

ps:理论上来说,只做纯签名是最快的。

// 纯签名 + 生成椭圆曲线点
String sigValueHex = Sm2.doSignature(msg, privateKey); // 签名
boolean verifyResult = Sm2.doVerifySignature(msg, sigValueHex, publicKey); // 验签结果

// 纯签名
Queue<Point> pointPool = new LinkedList(Arrays.asList(Sm2.getPoint(), Sm2.getPoint(), Sm2.getPoint(), Sm2.getPoint()));
SignatureOptions signatureOptions2 = new SignatureOptions();
signatureOptions2.setPointPool(pointPool); // 传入事先已生成好的椭圆曲线点,可加快签名速度
String sigValueHex2 = Sm2.doSignature(msg, privateKey, signatureOptions2);
boolean verifyResult2 = Sm2.doVerifySignature(msg, sigValueHex2, publicKey); // 验签结果

// 纯签名 + 生成椭圆曲线点 + der编解码
SignatureOptions signatureOptions3 = new SignatureOptions();
signatureOptions3.setDer(true);
String sigValueHex3 = Sm2.doSignature(msg, privateKey, signatureOptions3); // 签名
boolean verifyResult3 = Sm2.doVerifySignature(msg, sigValueHex3, publicKey, signatureOptions3); // 验签结果

// 纯签名 + 生成椭圆曲线点 + sm3杂凑
SignatureOptions signatureOptions4 = new SignatureOptions();
signatureOptions4.setHash(true);
String sigValueHex4 = Sm2.doSignature(msg, privateKey, signatureOptions4); // 签名
boolean verifyResult4 = Sm2.doVerifySignature(msg, sigValueHex4, publicKey, signatureOptions4); // 验签结果

// 纯签名 + 生成椭圆曲线点 + sm3杂凑(不做公钥推导)
SignatureOptions signatureOptions5 = new SignatureOptions();
signatureOptions5.setHash(true);
signatureOptions5.setPublicKey(publicKey); // 传入公钥的话,可以去掉sm3杂凑中推导公钥的过程,速度会比纯签名 + 生成椭圆曲线点 + sm3杂凑快
String sigValueHex5 = Sm2.doSignature(msg, privateKey, signatureOptions5); // 签名
boolean verifyResult5 = Sm2.doVerifySignature(msg, sigValueHex5, publicKey, signatureOptions5); // 验签结果

// 纯签名 + 生成椭圆曲线点 + sm3杂凑 + 不做公钥推 + 添加 userId(长度小于 8192)
// 默认 userId 值为 1234567812345678
SignatureOptions signatureOptions6 = new SignatureOptions();
signatureOptions6.setHash(true);
signatureOptions6.setPublicKey(publicKey);
signatureOptions6.setUserId("testUserId");
String sigValueHex6 = Sm2.doSignature(msg, privateKey, signatureOptions6); // 签名
boolean verifyResult6 = Sm2.doVerifySignature(msg, sigValueHex6, publicKey, signatureOptions6); // 验签结果

获取椭圆曲线点

Point point = Sm2.getPoint(); // 获取一个椭圆曲线点,可在sm2签名时传入

sm3

String hashData = Sm3.sm3("abc"); // 杂凑

sm4

加密

String msg = "hello world! 我是 antherd.";
String key = "0123456789abcdeffedcba9876543210"; // 16 进制字符串,要求为 128 比特

String encryptData1 = Sm4.encrypt(msg, key); // 加密,默认使用 pkcs#5 填充,输出16进制字符串

Sm4Options sm4Options2 = new Sm4Options();
sm4Options2.setPadding("none");
String encryptData2 = Sm4.encrypt(msg, key, sm4Options2); // 加密,不使用 padding,输出16进制字符串

Sm4Options sm4Options3 = new Sm4Options();
sm4Options3.setPadding("none");
byte[] encryptData3 = Sm4.hexToBytes(Sm4.encrypt(msg, key, sm4Options3)); // 加密,不使用 padding,输出转为字节数组

Sm4Options sm4Options4 = new Sm4Options();
sm4Options4.setMode("cbc");
sm4Options4.setIv("fedcba98765432100123456789abcdef");
String encryptData4 = Sm4.encrypt(msg, key, sm4Options4); // 加密,cbc 模式,输出16进制字符串

解密

String encryptData = "0e395deb10f6e8a17e17823e1fd9bd98a1bff1df508b5b8a1efb79ec633d1bb129432ac1b74972dbe97bab04f024e89c"; // 加密后的 16 进制字符串
String key = "0123456789abcdeffedcba9876543210"; // 16 进制字符串,要求为 128 比特

String decryptData5 = Sm4.decrypt(encryptData, key); // 解密,默认使用 pkcs#5 填充,输出 utf8 字符串

Sm4Options sm4Options6 = new Sm4Options();
sm4Options6.setPadding("none");
String decryptData6 = Sm4.decrypt(encryptData, key, sm4Options6); // 解密,不使用 padding,输出 utf8 字符串

Sm4Options sm4Options7 = new Sm4Options();
sm4Options7.setPadding("none");
byte[] decryptData7 = Sm4.utf8ToArray(Sm4.decrypt(encryptData, key, sm4Options7)); // 解密,不使用 padding,输出转为字节数组

Sm4Options sm4Options8 = new Sm4Options();
sm4Options8.setMode("cbc");
sm4Options8.setIv("fedcba98765432100123456789abcdef");
String decryptData8 = Sm4.decrypt(encryptData, key, sm4Options8); // 解密,cbc 模式,输出 utf8 字符串

在这里插入图片描述

很高兴回答你的问题!以下是一个使用国密算法SM2-SM3)的Java Demo Maven工程,供您参考: 1. 首先,在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>com.huawei.security</groupId> <artifactId>sm</artifactId> <version>2.0.5.300</version> </dependency> ``` 2. 创建SM2密钥对 ```java import com.huawei.security.sm.SM2KeyPair; import com.huawei.security.sm.SM2PrivateKey; import com.huawei.security.sm.SM2PublicKey; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; public class SM2Demo { public static void main(String[] args) throws NoSuchProviderException, NoSuchAlgorithmException { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); SM2KeyPair sm2KeyPair = new SM2KeyPair(); SM2PublicKey publicKey = sm2KeyPair.getPublicKey(); SM2PrivateKey privateKey = sm2KeyPair.getPrivateKey(); System.out.println("publicKey: " + publicKey.getHexString()); System.out.println("privateKey: " + privateKey.getHexString()); } } ``` 3. SM2加密和解密 ```java import com.huawei.security.sm.SM2PrivateKey; import com.huawei.security.sm.SM2PublicKey; import com.huawei.security.sm.SM2Engine; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyPairGenerator; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; public class SM2Demo { public static void main(String[] args) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); // 创建密钥对 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC"); keyPairGenerator.initialize(256); SM2KeyPair sm2KeyPair = new SM2KeyPair(keyPairGenerator.generateKeyPair()); // 获取公钥和私钥 SM2PublicKey publicKey = sm2KeyPair.getPublicKey(); SM2PrivateKey privateKey = sm2KeyPair.getPrivateKey(); // 加密 SM2Engine sm2Engine = new SM2Engine(); Cipher cipher = Cipher.getInstance(sm2Engine.getAlgorithmName(), "BC"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] plaintext = "Hello, world!".getBytes(); byte[] ciphertext = cipher.doFinal(plaintext); System.out.println("ciphertext: " + new String(ciphertext)); // 解密 cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decrypted = cipher.doFinal(ciphertext); System.out.println("decrypted: " + new String(decrypted)); } } ``` 4. SM3哈希算法 ```java import com.huawei.security.sm.SM3Digest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; public class SM3Demo { public static void main(String[] args) throws NoSuchProviderException, NoSuchAlgorithmException { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); // 计算哈希值 SM3Digest sm3Digest = new SM3Digest(); byte[] plaintext = "Hello, world!".getBytes(); sm3Digest.update(plaintext, 0, plaintext.length); byte[] hash = new byte[sm3Digest.getDigestSize()]; sm3Digest.doFinal(hash, 0); System.out.println("hash: " + org.bouncycastle.util.encoders.Hex.toHexString(hash)); } } ``` 希望这个Demo工程能够帮助您使用国密算法SM2-SM3)的Java开发。如果您有任何疑问,请随时联系我!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小工匠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值