springboot sm4 cbc加解密完整实现
时间: 2023-09-26 11:13:45 浏览: 170
下面是一个使用Spring Boot和SM4 CBC加解密的完整实现示例:
1. 添加依赖
在`pom.xml`文件中添加以下依赖:
```xml
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.64</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.64</version>
</dependency>
```
这些依赖包含了Bouncy Castle加密库。
2. 创建SM4加解密工具类
创建一个名为`SM4Utils`的工具类,其中包含SM4加解密的方法。
```java
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;
public class SM4Utils {
private static final String ALGORITHM_NAME = "SM4";
private static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS7Padding";
private static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS7Padding";
private static final String IV_PARAMETER = "0000000000000000";
static {
Security.addProvider(new BouncyCastleProvider());
}
public static String encryptECB(String key, String plaintext) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, BouncyCastleProvider.PROVIDER_NAME);
byte[] keyBytes = Hex.decode(key);
byte[] plaintextBytes = plaintext.getBytes();
SecretKeySpec sm4Key = new SecretKeySpec(keyBytes, ALGORITHM_NAME);
cipher.init(Cipher.ENCRYPT_MODE, sm4Key);
byte[] ciphertextBytes = cipher.doFinal(plaintextBytes);
return new String(Hex.encode(ciphertextBytes));
} catch (Exception e) {
throw new RuntimeException("SM4 ECB encrypt failed.", e);
}
}
public static String decryptECB(String key, String ciphertext) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, BouncyCastleProvider.PROVIDER_NAME);
byte[] keyBytes = Hex.decode(key);
byte[] ciphertextBytes = Hex.decode(ciphertext);
SecretKeySpec sm4Key = new SecretKeySpec(keyBytes, ALGORITHM_NAME);
cipher.init(Cipher.DECRYPT_MODE, sm4Key);
byte[] plaintextBytes = cipher.doFinal(ciphertextBytes);
return new String(plaintextBytes);
} catch (Exception e) {
throw new RuntimeException("SM4 ECB decrypt failed.", e);
}
}
public static String encryptCBC(String key, String iv, String plaintext) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC_PADDING, BouncyCastleProvider.PROVIDER_NAME);
byte[] keyBytes = Hex.decode(key);
byte[] ivBytes = Hex.decode(iv);
byte[] plaintextBytes = plaintext.getBytes();
SecretKeySpec sm4Key = new SecretKeySpec(keyBytes, ALGORITHM_NAME);
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.ENCRYPT_MODE, sm4Key, ivParameterSpec);
byte[] ciphertextBytes = cipher.doFinal(plaintextBytes);
return new String(Hex.encode(ciphertextBytes));
} catch (Exception e) {
throw new RuntimeException("SM4 CBC encrypt failed.", e);
}
}
public static String decryptCBC(String key, String iv, String ciphertext) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC_PADDING, BouncyCastleProvider.PROVIDER_NAME);
byte[] keyBytes = Hex.decode(key);
byte[] ivBytes = Hex.decode(iv);
byte[] ciphertextBytes = Hex.decode(ciphertext);
SecretKeySpec sm4Key = new SecretKeySpec(keyBytes, ALGORITHM_NAME);
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.DECRYPT_MODE, sm4Key, ivParameterSpec);
byte[] plaintextBytes = cipher.doFinal(ciphertextBytes);
return new String(plaintextBytes);
} catch (Exception e) {
throw new RuntimeException("SM4 CBC decrypt failed.", e);
}
}
}
```
3. 创建一个RESTful API
在`RestController`中创建一个RESTful API,该API将加密和解密请求发送到`SM4Utils`工具类。
```java
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/sm4")
public class SM4Controller {
@PostMapping("/encrypt/ecb")
public String encryptECB(@RequestParam("key") String key, @RequestParam("plaintext") String plaintext) {
return SM4Utils.encryptECB(key, plaintext);
}
@PostMapping("/decrypt/ecb")
public String decryptECB(@RequestParam("key") String key, @RequestParam("ciphertext") String ciphertext) {
return SM4Utils.decryptECB(key, ciphertext);
}
@PostMapping("/encrypt/cbc")
public String encryptCBC(@RequestParam("key") String key, @RequestParam(value = "iv", defaultValue = IV_PARAMETER) String iv, @RequestParam("plaintext") String plaintext) {
return SM4Utils.encryptCBC(key, iv, plaintext);
}
@PostMapping("/decrypt/cbc")
public String decryptCBC(@RequestParam("key") String key, @RequestParam(value = "iv", defaultValue = IV_PARAMETER) String iv, @RequestParam("ciphertext") String ciphertext) {
return SM4Utils.decryptCBC(key, iv, ciphertext);
}
}
```
4. 测试API
使用Postman或类似的工具测试RESTful API。以下是一些示例请求和响应:
加密请求:
```http
POST /sm4/encrypt/ecb?key=12345678901234567890123456789012&plaintext=Hello%20world! HTTP/1.1
Host: localhost:8080
```
加密响应:
```
8ad6a9d9b5b5139dc6c6c3d4ee92f3f5
```
解密请求:
```http
POST /sm4/decrypt/ecb?key=12345678901234567890123456789012&ciphertext=8ad6a9d9b5b5139dc6c6c3d4ee92f3f5 HTTP/1.1
Host: localhost:8080
```
解密响应:
```
Hello world!
```
加密请求:
```http
POST /sm4/encrypt/cbc?key=12345678901234567890123456789012&iv=0000000000000000&plaintext=Hello%20world! HTTP/1.1
Host: localhost:8080
```
加密响应:
```
4d7d881e1ebe6f9f2d1d7d1f2a5d3d0d
```
解密请求:
```http
POST /sm4/decrypt/cbc?key=12345678901234567890123456789012&iv=0000000000000000&ciphertext=4d7d881e1ebe6f9f2d1d7d1f2a5d3d0d HTTP/1.1
Host: localhost:8080
```
解密响应:
```
Hello world!
```
阅读全文