本文目录导读:

我将为您提供Java接口加解密的完整案例,包括对称加密(AES)和非对称加密(RSA)两种方案。
AES对称加解密方案
1 AES工具类
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
/**
* AES-GCM加密工具类
* 使用AES-128/256位加密,GCM模式(支持认证)
*/
public class AesUtil {
private static final String AES = "AES";
private static final String AES_GCM = "AES/GCM/NoPadding";
private static final int IV_LENGTH = 12; // GCM推荐IV长度
private static final int TAG_LENGTH = 128; // 认证标签长度
/**
* 生成AES密钥
*/
public static String generateKey() throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance(AES);
keyGen.init(256, new SecureRandom());
SecretKey secretKey = keyGen.generateKey();
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
}
/**
* 加密数据
* @param plainText 明文
* @param base64Key Base64编码的密钥
* @return Base64编码的密文(包含IV)
*/
public static String encrypt(String plainText, String base64Key) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(base64Key);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, AES);
byte[] iv = new byte[IV_LENGTH];
new SecureRandom().nextBytes(iv);
Cipher cipher = Cipher.getInstance(AES_GCM);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new GCMParameterSpec(TAG_LENGTH, iv));
byte[] cipherText = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
// 将IV和密文拼接返回
byte[] result = new byte[iv.length + cipherText.length];
System.arraycopy(iv, 0, result, 0, iv.length);
System.arraycopy(cipherText, 0, result, iv.length, cipherText.length);
return Base64.getEncoder().encodeToString(result);
}
/**
* 解密数据
*/
public static String decrypt(String encryptedData, String base64Key) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(base64Key);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, AES);
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
// 提取IV和密文
byte[] iv = new byte[IV_LENGTH];
byte[] cipherText = new byte[encryptedBytes.length - IV_LENGTH];
System.arraycopy(encryptedBytes, 0, iv, 0, iv.length);
System.arraycopy(encryptedBytes, iv.length, cipherText, 0, cipherText.length);
Cipher cipher = Cipher.getInstance(AES_GCM);
cipher.init(Cipher.DECRYPT_MODE, keySpec, new GCMParameterSpec(TAG_LENGTH, iv));
byte[] plainText = cipher.doFinal(cipherText);
return new String(plainText, StandardCharsets.UTF_8);
}
}
2 AES拦截器实现
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.stream.Collectors;
/**
* AES接口加密拦截器
*/
public class AesInterceptor implements HandlerInterceptor {
private static final String AES_KEY = "your-aes-key-here-256bit"; // 建议从配置中心获取
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 只处理POST请求
if ("POST".equals(request.getMethod())) {
// 读取请求体
BufferedReader reader = request.getReader();
String body = reader.lines().collect(Collectors.joining());
if (body != null && !body.isEmpty()) {
try {
// 解密请求数据
String decrypted = AesUtil.decrypt(body, AES_KEY);
// 将解密后的数据封装为新的请求
request.setAttribute("decryptedBody", decrypted);
} catch (Exception e) {
response.setStatus(400);
response.getWriter().write("{\"error\":\"Invalid encrypted data\"}");
return false;
}
}
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
// 响应加密逻辑可以在ResponseBodyAdvice中处理
}
}
3 AES响应加密配置
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.HashMap;
import java.util.Map;
/**
* AES响应加密处理
*/
@ControllerAdvice
public class AesResponseAdvice implements ResponseBodyAdvice<Object> {
private static final String AES_KEY = "your-aes-key-here-256bit";
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// 自定义需要加密的注解或条件
return returnType.hasMethodAnnotation(EncryptResponse.class);
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
try {
// 将响应数据加密
String jsonData = new ObjectMapper().writeValueAsString(body);
String encrypted = AesUtil.encrypt(jsonData, AES_KEY);
Map<String, String> result = new HashMap<>();
result.put("data", encrypted);
return result;
} catch (Exception e) {
return body;
}
}
}
/**
* 自定义注解,标记需要加密的响应
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptResponse {
}
RSA非对称加解密方案
1 RSA工具类
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
/**
* RSA加密工具类
*/
public class RsaUtil {
private static final String RSA_ALGORITHM = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
/**
* 生成密钥对
*/
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
return keyPairGenerator.generateKeyPair();
}
/**
* 使用公钥加密
*/
public static String encrypt(String data, String publicKey) throws Exception {
PublicKey key = getPublicKey(publicKey);
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedBytes = cipher.doFinal(data.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* 使用私钥解密
*/
public static String decrypt(String encryptedData, String privateKey) throws Exception {
PrivateKey key = getPrivateKey(privateKey);
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decryptedBytes, "UTF-8");
}
/**
* 使用私钥签名
*/
public static String sign(String data, String privateKey) throws Exception {
PrivateKey key = getPrivateKey(privateKey);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(key);
signature.update(data.getBytes("UTF-8"));
byte[] signatureBytes = signature.sign();
return Base64.getEncoder().encodeToString(signatureBytes);
}
/**
* 使用公钥验签
*/
public static boolean verify(String data, String signature, String publicKey) throws Exception {
PublicKey key = getPublicKey(publicKey);
Signature verifySignature = Signature.getInstance("SHA256withRSA");
verifySignature.initVerify(key);
verifySignature.update(data.getBytes("UTF-8"));
return verifySignature.verify(Base64.getDecoder().decode(signature));
}
private static PublicKey getPublicKey(String base64Key) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(base64Key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}
private static PrivateKey getPrivateKey(String base64Key) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(base64Key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
}
2 混合加密方案(推荐)
import java.util.HashMap;
import java.util.Map;
/**
* 混合加密服务(AES + RSA)
* 使用RSA加密AES密钥,AES加密数据
*/
@Service
public class HybridEncryptionService {
// RSA公钥和私钥应该是从配置或密钥管理系统中获取
private static final String RSA_PUBLIC_KEY = "your-rsa-public-key";
private static final String RSA_PRIVATE_KEY = "your-rsa-private-key";
/**
* 加密请求数据
*/
public Map<String, String> encryptRequest(Object data) throws Exception {
Map<String, String> result = new HashMap<>();
// 1. 生成一次性的AES密钥
String aesKey = AesUtil.generateKey();
// 2. 使用AES加密数据
String jsonData = new ObjectMapper().writeValueAsString(data);
String encryptedData = AesUtil.encrypt(jsonData, aesKey);
// 3. 使用RSA公钥加密AES密钥
String encryptedAesKey = RsaUtil.encrypt(aesKey, RSA_PUBLIC_KEY);
result.put("data", encryptedData);
result.put("key", encryptedAesKey);
return result;
}
/**
* 解密响应数据
*/
public Object decryptResponse(Map<String, String> encryptedData, Class<?> targetClass) throws Exception {
// 1. 使用RSA私钥解密AES密钥
String aesKey = RsaUtil.decrypt(encryptedData.get("key"), RSA_PRIVATE_KEY);
// 2. 使用AES密钥解密数据
String jsonData = AesUtil.decrypt(encryptedData.get("data"), aesKey);
// 3. 转换为目标对象
return new ObjectMapper().readValue(jsonData, targetClass);
}
}
完整接口示例
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private HybridEncryptionService encryptionService;
@Autowired
private UserService userService;
/**
* 加密的POST请求
*/
@PostMapping("/user/encrypted")
@EncryptResponse
public ResponseEntity<?> createUser(@RequestBody Map<String, String> encryptedRequest) {
try {
// 解密请求数据
UserRequest userRequest = (UserRequest) encryptionService.decryptResponse(
encryptedRequest, UserRequest.class);
// 处理业务逻辑
User user = userService.createUser(userRequest);
// 返回加密的响应
Map<String, String> response = encryptionService.encryptRequest(user);
return ResponseEntity.ok(response);
} catch (Exception e) {
return ResponseEntity.badRequest().body("Decryption failed: " + e.getMessage());
}
}
/**
* 简单AES加密的请求
*/
@PostMapping("/user/aes")
public ResponseEntity<?> createUserAes(@RequestBody EncryptedRequest request) {
try {
String decryptedData = AesUtil.decrypt(
request.getData(),
ConfigProperties.get("aes.key")
);
UserRequest userRequest = new ObjectMapper()
.readValue(decryptedData, UserRequest.class);
User user = userService.createUser(userRequest);
Map<String, String> response = new HashMap<>();
response.put("encrypted", "true");
response.put("data", AesUtil.encrypt(
new ObjectMapper().writeValueAsString(user),
ConfigProperties.get("aes.key")
));
return ResponseEntity.ok(response);
} catch (Exception e) {
return ResponseEntity.badRequest().body("Processing failed");
}
}
}
/**
* 加密请求DTO
*/
public class EncryptedRequest {
private String data;
private String key;
// getters and setters...
}
配置文件
# application.yml
encryption:
aes:
key: your-aes-key-here-256bit
rsa:
public-key: your-rsa-public-key
private-key: your-rsa-private-key
enabled: true
exclude-paths:
- /api/public
- /api/health
客户端调用示例
public class ApiClient {
private RestTemplate restTemplate = new RestTemplate();
/**
* 发送加密请求
*/
public void sendEncryptedRequest() throws Exception {
// 准备数据
UserRequest request = new UserRequest();
request.setName("张三");
request.setPhone("13800001234");
// 获取服务器RSA公钥(可以从认证接口获取)
String rsaPublicKey = getServerPublicKey();
// 生成AES密钥
String aesKey = AesUtil.generateKey();
// 使用AES加密数据
String jsonData = new ObjectMapper().writeValueAsString(request);
String encryptedData = AesUtil.encrypt(jsonData, aesKey);
// 使用RSA公钥加密AES密钥
String encryptedAesKey = RsaUtil.encrypt(aesKey, rsaPublicKey);
// 构建请求
Map<String, String> body = new HashMap<>();
body.put("data", encryptedData);
body.put("key", encryptedAesKey);
// 发送请求
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, String>> entity = new HttpEntity<>(body, headers);
ResponseEntity<Map> response = restTemplate.exchange(
"https://api.example.com/api/user/encrypted",
HttpMethod.POST,
entity,
Map.class
);
// 解密响应
if (response.getStatusCode() == HttpStatus.OK) {
Map<String, String> responseBody = response.getBody();
// 使用私钥解密AES密钥(客户端需要持有私钥)
String decryptedAesKey = RsaUtil.decrypt(
responseBody.get("key"),
getClientPrivateKey()
);
// 使用AES密钥解密数据
String decryptedData = AesUtil.decrypt(
responseBody.get("data"),
decryptedAesKey
);
System.out.println("解密后的响应: " + decryptedData);
}
}
}
安全建议
// 1. 密钥管理
public class KeyManagementUtil {
// 定期轮换密钥
@Scheduled(cron = "0 0 0 * * ?")
public void rotateKeys() {
// 生成新密钥
// 更新到配置中心
// 定期清理旧密钥
}
// 防止重放攻击
public boolean validateTimestamp(String timestamp) {
long requestTime = Long.parseLong(timestamp);
long currentTime = System.currentTimeMillis();
return Math.abs(currentTime - requestTime) < 300000; // 5分钟有效
}
// 添加请求签名
public String generateSignature(String data, String key) {
try {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(
key.getBytes(), "HmacSHA256"
);
mac.init(secretKeySpec);
return Base64.getEncoder().encodeToString(
mac.doFinal(data.getBytes())
);
} catch (Exception e) {
throw new RuntimeException("签名生成失败", e);
}
}
}
// 2. 日志脱敏
public class SensitiveDataUtil {
private static final Pattern PHONE_PATTERN = Pattern.compile("(\\d{3})\\d{4}(\\d{4})");
public static String desensitize(String data) {
if (data == null) return null;
// 手机号脱敏
data = PHONE_PATTERN.matcher(data).replaceAll("$1****$2");
// 其他敏感信息处理...
return data;
}
}
这个完整的案例涵盖了:
- AES对称加密 - 适合大规模数据传输
- RSA非对称加密 - 用于密钥交换和数字签名
- 混合加密方案 - 推荐的生产级方案
- 拦截器实现 - 自动处理加密解密
- 安全配置 - 密钥管理、防重放攻击等
使用时请根据实际需求选择合适的方案,并确保密钥安全存储。