1. Why do interface data encryption and decryption need?
In scenarios such as financial payments and user privacy information transmission, if the interface data is transmitted in plain text, it is very easy to be stolen by man-in-the-middle attacks. For example:
- Sensitive information such as password, ID number when logging in
- Core business parameters of data interaction among enterprises
- Token credentials for mobile and background interaction
Spring Boot provides a variety of elegant encryption and decryption implementation solutions, which can not only ensure data security but also minimize business intrusion. This article will take you to master three mainstream implementation methods from principles to actual combat.
2. Selection of core encryption and decryption algorithms
1. Symmetric encryption (AES)
Advantages: Fast encryption speed, suitable for large-traffic data transmission Disadvantages: The key needs to be stored securely, suitable for one-to-one scenarios between clients and servers
// AES tool class (128-bit key)public class AESUtils { private static final String KEY = "your_16bit_secret_key"; private static final String ALGORITHM = "AES/ECB/PKCS5Padding"; public static String encrypt(String data) throws Exception { Cipher cipher = (ALGORITHM); (Cipher.ENCRYPT_MODE, new SecretKeySpec((), "AES")); return ().encodeToString((())); } public static String decrypt(String data) throws Exception { Cipher cipher = (ALGORITHM); (Cipher.DECRYPT_MODE, new SecretKeySpec((), "AES")); return new String((().decode(data))); } }
2. Asymmetric encryption (RSA)
Advantages: Key pair mechanism, suitable for certificate authentication scenarios Disadvantages: Inefficient encryption, usually used to encrypt symmetric keys
// RSA tool class (generate public key private key pair)public class RSAUtils { private static final int KEY_SIZE = 1024; private static final String ALGORITHM = "RSA"; public static Map<String, String> generateKeyPair() throws Exception { KeyPairGenerator generator = (ALGORITHM); (KEY_SIZE); KeyPair pair = (); return ( "publicKey", ().encodeToString(().getEncoded()), "privateKey", ().encodeToString(().getEncoded()) ); } }
3. Practical Solution 1: Transparent encryption and decryption based on AOP
1. Core Principle
By customizing the interface that needs to be encrypted and decrypted, Spring AOP automatically handles the encrypted and decrypted logic before and after method calls, achieving zero intrusion of business code.
2. Implementation steps
(1) Define the encryption and decryption annotation
@Target() @Retention() public @interface Encrypt { // Exclude fields (such as timestamps, etc. without encrypting fields) String[] excludeFields() default {}; } @Target() @Retention() public @interface Decrypt { // Is an exception thrown if the decryption fails boolean throwOnFailure() default true; }
(2) Write AOP facets
@Aspect @Component public class DataEncryptAspect { @Around("@annotation(Encrypt)") public Object encryptAround(ProceedingJoinPoint joinPoint) throws Throwable { // Execute the original method Object result = (); // AES encryption of the response results return ((result)); } @Around("@annotation(Decrypt)") public Object decryptAround(ProceedingJoinPoint joinPoint) throws Throwable { // Get the request parameter (assuming the parameter is a JSON string) Object[] args = (); String encryptedData = (String) args[0]; // Decrypt the request parameters String decryptedData = (encryptedData); // Replace the original parameter with decrypted data args[0] = decryptedData; return (args); } }
(3) Example of controller usage
@RestController @RequestMapping("/api") public class UserController { @PostMapping("/register") @Decrypt public UserRegisterResponse register(@RequestBody String encryptedData) { // Process the decrypted plaintext data UserRegisterRequest request = (encryptedData, ); // Business logic... return new UserRegisterResponse("Registered successfully", ()); } @GetMapping("/profile") @Encrypt public UserProfile getProfile(@RequestParam String userId) { // Business logic to obtain user information return new UserProfile("Zhang San", "138****1234"); } }
3. Program Advantages
- Low intrusion: only need to add annotations to the interface method
- Flexible configuration: Customizable exclusion fields and exception handling strategies
- Applicable scenarios: suitable for fine-grained control of a single interface
4. Practical Solution 2: Global filter implements request response encryption and decryption
1. Core Principle
By implementing Filter or HandlerInterceptor, the parameters are decrypted before requesting to enter the controller, and the encryption result before leaving is implemented, and global unified encryption and decryption is achieved.
2. Implementation steps
(1) Custom encryption and decryption filter
@Component public class DataEncryptFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // Process the request decryption (assuming the request body is encrypted JSON) HttpServletRequest httpRequest = (HttpServletRequest) request; String encryptedBody = ((), StandardCharsets.UTF_8); String decryptedBody = (encryptedBody); // The package request body is a repetitive stream HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(httpRequest, decryptedBody); // Process response encryption final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper((HttpServletResponse) response, buffer); (requestWrapper, responseWrapper); // Encrypt and write the response result String encryptedResult = (()); ().write(encryptedResult); } } // Request the wrapper class (rewrite getInputStream)class HttpServletRequestWrapper extends HttpServletRequestWrapper { private final String body; public HttpServletRequestWrapper(HttpServletRequest request, String body) { super(request); = body; } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bis = new ByteArrayInputStream(()); return new ServletInputStream() { @Override public int read() throws IOException { return (); } //Omit other abstract method implementations }; } }
(2) Configure filters to take effect
@Configuration public class FilterConfig { @Bean public FilterRegistrationBean<DataEncryptFilter> encryptFilterRegistration() { FilterRegistrationBean<DataEncryptFilter> registration = new FilterRegistrationBean<>(); (new DataEncryptFilter()); ("/api/v1/**"); // Configure the interface path that needs to be encrypted and decrypted (Ordered.HIGHEST_PRECEDENCE); // Ensure filter execution is preferred return registration; } }
3. Program Advantages
- Global Unification: One-time configuration, all interfaces are automatically encrypted and decrypted
- High performance: based on stream processing to avoid performance losses caused by reflection
- Applicable scenarios: Global data encryption suitable for front-end and back-end separation projects
5. Practical solution 3: Customize MessageConverter to achieve transparent encryption and decryption
1. Core Principle
Rewrite Spring MVC's HttpMessageConverter, automatically completes encryption and decryption during the request parameter analysis and response data serialization stage, and deeply integrates with the framework.
2. Implementation steps
(1) Custom encryption and decryption converter
public class EncryptingHttpMessageConverter extends AbstractHttpMessageConverter<Object> { @Override protected boolean supports(Class<?> clazz) { return true; // Support all types } @Override protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { // Read the encrypted request body and decrypt it String encrypted = ((), StandardCharsets.UTF_8); String decrypted = (encrypted); return (decrypted, clazz); } @Override protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { // Encrypt the response object and write it out String plain = (object); String encrypted = (plain); ().write((StandardCharsets.UTF_8)); } }
(2) Register a custom converter
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { (new EncryptingHttpMessageConverter()); // Keep the default converter (optional) // ((new MappingJackson2HttpMessageConverter())); } }
3. Program Advantages
- Framework-level integration: Deep integration with Spring MVC data binding mechanism
- Type safety: Automatically handle the conversion of objects and encrypted strings
- Applicable scenarios: Suitable for scenarios where there is strict control over request/response formats
Six, three solutions and selection suggestions
Plan 1: AOP notes
Invasive: low
Performance: Zhongling
Activity: Interface-level control
Applicable scenarios: Some interfaces need to be encrypted and decrypted
Solution 2: Global filter
Invasive: Medium Performance: High
Flexibility: Path-level control
Applicable scenarios: Global encryption of front-end and back-end separation projects
Plan 3: MessageConverter
Invasive: High
Performance: Highest
Flexibility: Frame-level control
Applicable scenarios: Unified request response format scenarios
7. Best practices in production environment
1. Key management plan
- Disable hard coding: manage keys through Spring Config or configuration center (such as Nacos)
- Key rotation: generate new keys regularly, and the old keys are gradually phased out
- Hardware security: Sensitive systems use HSM (Hardware Security Module) to store keys
2. Exception handling mechanism
@RestControllerAdvice public class EncryptExceptionHandler { @ExceptionHandler() public ResponseEntity<String> handleDecryptionError(DecryptionException e) { return (HttpStatus.BAD_REQUEST) .body("Data decryption failed:" + ()); } }
3. Performance optimization skills
- Encryption after compression: compress large-volume data first and then encrypt (Gzip compression can reduce data volume by 50%)
- Asynchronous encryption and decryption: Use CompletableFuture to implement parallel processing of encryption and decryption and business logic
- Cache encryption results: cache encryption results of high-frequency access interfaces
8. Summary
Spring Boot provides a complete encryption and decryption solution from the interface level to the framework level, with the core of selecting the appropriate implementation method based on the business scenario:
- Pursuing flexibility and choosing AOP notes
- Pursuing unified selection global filter
- Pursuing framework integration and selection MessageConverter
No matter which solution, you need to pay attention to key security and exception handling. Through the source code examples in this article, developers can quickly implement the interface data encryption and decryption function in the project, ensuring data security while minimizing the impact on existing businesses.
The above is the detailed content of the three practical solutions for SpringBoot to implement interface data encryption and decryption. For more information about SpringBoot interface data encryption and decryption, please pay attention to my other related articles!