1.SM4简介
SM4是一种分组密码算法,其分组长度为128位(即16字节,4字),密钥长度也为128位(即16字节,4字)。其加解密过程采用了32轮迭代机制(与DES、AES类似),每一轮需要一个轮密钥(与DES、AES类似)。
加密过程分为两步,由32次轮迭代和1次反序变换组成。
SM4的解密过程与加密过程完全相同,也包括32轮迭代和一次反序变换。只是在轮迭代的时候,需要将轮密钥逆序使用。
2.如何使用
1.导入依赖
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.56</version>
</dependency>
2.代码
EncryptionInterceptor.java
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.lin.test.demo.controller.TestController;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.apache.tomcat.util.codec.binary.Base64;
import java.security.Security;
@Component
public class EncryptionInterceptor implements HandlerInterceptor {
@Autowired
private TestController testController;
private static final String KEY = "1234567890123456"; //16字节密钥
private static final String IV_PARAMETER = "abcdef0123456789"; //16字节IV参数
static {
Security.addProvider(new BouncyCastleProvider());
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle方法------------1111");
//加密请求参数
String requestData = request.getParameter("data");
if (requestData != null) {
String encryptedData = encrypt(requestData);
System.err.println(encryptedData);
}
System.out.println("preHandle方法------------22222");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle------------11111");
//解密响应数据
String responseData = request.getParameter("data");
if (responseData != null) {
String decryptedData = decrypt(responseData);
System.err.println(decryptedData);
}
System.out.println("postHandle------------22222");
}
//加密
private static String encrypt(String data) throws Exception {
byte[] keyBytes = KEY.getBytes();
byte[] ivBytes = IV_PARAMETER.getBytes();
byte[] dataBytes = data.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "SM4");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encryptedBytes = cipher.doFinal(dataBytes);
return Base64.encodeBase64String(encryptedBytes);
}
//解密
private static String decrypt(String data) throws Exception {
byte[] keyBytes = KEY.getBytes();
byte[] ivBytes = IV_PARAMETER.getBytes();
byte[] dataBytes = Base64.decodeBase64(data);
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "SM4");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] decryptedBytes = cipher.doFinal(dataBytes);
return new String(decryptedBytes, "UTF-8");
}
}
WebConfig.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private EncryptionInterceptor encryptionInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(encryptionInterceptor).addPathPatterns("/**");
}
}