springboot实现 sm2传输加密解密 公钥私钥生成 完整实现带注释
在Spring Boot中实现SM2加密和解密,需要使用Bouncy Castle库。以下是实现步骤:
- 添加Bouncy Castle依赖
在pom.xml文件中添加以下依赖:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.64</version>
</dependency>
- 生成SM2公钥和私钥
使用Bouncy Castle库中的SM2KeyPairGenerator类生成公钥和私钥。以下是生成代码:
// 生成SM2密钥对
SM2KeyPairGenerator generator = new SM2KeyPairGenerator();
generator.initialize(new SM2KeyGenerationParameters(new SecureRandom(), new SM2Parameters()));
AsymmetricCipherKeyPair kp = generator.generateKeyPair();
ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters) kp.getPrivate();
ECPublicKeyParameters publicKey = (ECPublicKeyParameters) kp.getPublic();
// 将公钥和私钥转换为字节数组
byte[] privateKeyBytes = privateKey.getD().toByteArray();
byte[] publicKeyBytes = publicKey.getQ().getEncoded(false);
- 加密数据
使用Bouncy Castle库中的SM2Engine类进行加密。以下是加密代码:
// 将明文和公钥转换为Bouncy Castle库中的类型
byte[] plaintextBytes = plaintext.getBytes(StandardCharsets.UTF_8);
ECPublicKeyParameters publicKey = new ECPublicKeyParameters(SM2Util.curve.decodePoint(publicKeyBytes), SM2Util.SM2_DEFAULT_CURVE);
// 加密数据
SM2Engine engine = new SM2Engine();
engine.init(true, new ParametersWithRandom(publicKey, new SecureRandom()));
byte[] ciphertextBytes = engine.processBlock(plaintextBytes, 0, plaintextBytes.length);
- 解密数据
使用Bouncy Castle库中的SM2Engine类进行解密。以下是解密代码:
// 将私钥和密文转换为Bouncy Castle库中的类型
ECPrivateKeyParameters privateKey = new ECPrivateKeyParameters(new BigInteger(1, privateKeyBytes), SM2Util.SM2_DEFAULT_CURVE);
byte[] ciphertextBytes = Base64.decodeBase64(ciphertext);
// 解密数据
SM2Engine engine = new SM2Engine();
engine.init(false, privateKey);
byte[] plaintextBytes = engine.processBlock(ciphertextBytes, 0, ciphertextBytes.length);
String plaintext = new String(plaintextBytes, StandardCharsets.UTF_8);
完整实现代码:
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.SM2KeyPairGenerator;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.util.encoders.Hex;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
public class SM2Util {
public static final String SM2_DEFAULT_CURVE = "sm2p256v1";
public static final X9ECParameters curve = CustomNamedCurves.getByName(SM2_DEFAULT_CURVE);
/**
* 生成SM2密钥对
*
* @return 密钥对,包含公钥和私钥
*/
public static SM2KeyPair generateSM2KeyPair() {
SM2KeyPairGenerator generator = new SM2KeyPairGenerator();
generator.initialize(new SM2KeyGenerationParameters(new SecureRandom(), new SM2Parameters()));
AsymmetricCipherKeyPair kp = generator.generateKeyPair();
ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters) kp.getPrivate();
ECPublicKeyParameters publicKey = (ECPublicKeyParameters) kp.getPublic();
byte[] privateKeyBytes = privateKey.getD().toByteArray();
byte[] publicKeyBytes = publicKey.getQ().getEncoded(false);
return new SM2KeyPair(privateKeyBytes, publicKeyBytes);
}
/**
* SM2加密
*
* @param plaintext 明文
* @param publicKey 公钥
* @return 加密后的密文
*/
public static String encryptSM2(String plaintext, byte[] publicKey) {
try {
// 将明文和公钥转换为Bouncy Castle库中的类型
byte[] plaintextBytes = plaintext.getBytes(StandardCharsets.UTF_8);
ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(curve.decodePoint(publicKey), curve);
// 加密数据
SM2Engine engine = new SM2Engine();
engine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));
byte[] ciphertextBytes = engine.processBlock(plaintextBytes, 0, plaintextBytes.length);
// 返回Base64编码的密文
return Base64.encodeBase64String(ciphertextBytes);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* SM2解密
*
* @param ciphertext 密文
* @param privateKey 私钥
* @return 解密后的明文
*/
public static String decryptSM2(String ciphertext, byte[] privateKey) {
try {
// 将私钥和密文转换为Bouncy Castle库中的类型
ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(new BigInteger(1, privateKey), curve);
byte[] ciphertextBytes = Base64.decodeBase64(ciphertext);
// 解密数据
SM2Engine engine = new SM2Engine();
engine.init(false, privateKeyParameters);
byte[] plaintextBytes = engine.processBlock(ciphertextBytes, 0, ciphertextBytes.length);
// 返回解密后的明文
return new String(plaintextBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* SM2密钥对
*/
public static class SM2KeyPair {
private final byte[] privateKey;
private final byte[] publicKey;
public SM2KeyPair(byte[] privateKey, byte[] publicKey) {
this.privateKey = privateKey;
this.publicKey = publicKey;
}
public byte[] getPrivateKey() {
return privateKey;
}
public byte[] getPublicKey() {
return publicKey;
}
}
public static void main(String[] args) {
// 生成SM2密钥对
SM2KeyPair keyPair = generateSM2KeyPair();
byte[] privateKey = keyPair.getPrivateKey();
byte[] publicKey = keyPair.getPublicKey();
System.out.println("SM2私钥:" + Hex.toHexString(privateKey));
System.out.println("SM2公钥:" + Hex.toHexString(publicKey));
// 加密数据
String plaintext = "Hello, SM2!";
String ciphertext = encryptSM2(plaintext, publicKey);
System.out.println("加密后的密文:" + ciphertext);
// 解密数据
String decryptedText = decryptSM2(ciphertext, privateKey);
System.out.println("解密后的明文:" + decryptedText);
}
}
以上就是使用Spring Boot实现SM2加密和解密的完整代码
原文地址: https://www.cveoy.top/t/topic/e2bT 著作权归作者所有。请勿转载和采集!