Rpamis-security Documentation

website·Indexed 30 days ago

https://docs.security.rpamis.com

An enterprise-grade data security component implemented as a MyBatis plugin. It provides functionality for data encryption and decryption, data masking (desensitization) via the @Desensitizationed annotation, and dynamic SQL encryption using the MybatisDynamicSqlEncryptInterceptor.

Tokens
10.6K
Snippets
49
Records
59
Agent score
49%

What's inside Rpamis-security

  1. Overview of Rpamis-security Architecture

    Rpamis-security is an enterprise-grade data security component implemented as a MyBatis plugin. It provides annotation-driven data masking and encryption/decryption to solve common pain points such as repetitive encryption logic, inconsistent masking standards, and high maintenance costs. The architecture is divided into three main layers: an Annotation module for marking fields, a Core module for processing logic, and a Spring Boot Auto-configuration module for seamless integration.
  2. Overview of Rpamis-Security

    Rpamis-Security is a MyBatis-based security component designed for enterprise data security. It provides annotation-driven data desensitization and automatic database encryption/decryption. Key features include support for 9 built-in desensitization rules, SM4 national standard encryption, support for nested types (List, Map), and a flexible configuration system for failure handling and algorithm selection.
  3. Implement automatic data encryption and decryption in MyBatis

    Rpamis-security provides a MyBatis plugin that automatically encrypts data when it is inserted or updated in the database and decrypts it when retrieved. The process is transparent to the service layer: the plugin intercepts SQL execution to detect fields marked for security, applies the configured encryption algorithm, and prepends a specific prefix to identify encrypted data. During retrieval, the plugin detects this prefix to trigger decryption.
  4. Understand the Rpamis-security data encryption and decryption workflow

    Rpamis-security implements data security via MyBatis interceptors.

    Encryption Workflow (Data Inbound):

    1. A Service method calls a MyBatis operation (e.g., insert).
    2. MybatisEncryptInterceptor.intercept triggers.
    3. The system performs a deep copy of the source object to prevent modifying original references.
    4. SecurityUtils.encrypt encrypts the target fields (checking prefixes to prevent double encryption).
    5. The encrypted parameters are set into the parameterHandler and the SQL is executed.

    Decryption Workflow (Data Outbound):

    1. A Service method calls a MyBatis query (e.g., select).
    2. MybatisDecryptInterceptor.intercept triggers.
    3. The result set (supporting List, Map, etc.) is processed.
    4. SecurityUtils.decrypt decrypts the fields (checking prefixes to prevent double decryption).
    5. The decrypted objects are returned to the application.
  5. Install Rpamis-Security Spring Boot Starter

    Add the rpamis-security-spring-boot-starter dependency to your Maven project. Choose the version based on your JDK version.

    <!-- For JDK 17 and above --> <dependency> <groupId>com.rpamis</groupId> <artifactId>rpamis-security-spring-boot-starter</artifactId> <version>1.1.4</version> </dependency>

    <!-- For JDK 8 to JDK 17 --> <dependency> <groupId>com.rpamis</groupId> <artifactId>rpamis-security-spring-boot-starter</artifactId> <version>1.0.7</version> </dependency>

  6. Handle nested objects for desensitization with @NestedMasked

    When a return object contains nested objects, Lists, or Maps that also contain @Masked fields, use the @NestedMasked annotation on those fields. This instructs the security component to recursively process the nested structures for desensitization.
    @Data
    public class TestNestVO implements Serializable {
        @Masked(type = MaskType.NAME_MASK)
        private String name;
    
        @NestedMasked
        private TestVO testVO;
    
        @NestedMasked
        private List<TestVO> testVOList;
    
        @NestedMasked
        private Map<String, TestVO> testVOMap;
    }
  7. Create and use custom desensitization rules

    To implement a custom masking logic, create a class that implements the MaskFunction interface. Then, apply the @Masked annotation to the field in your VO, setting the type to MaskType.CUSTOM_MASK and specifying the start/end indices and the masking symbol.
    // 1. Implement the custom masking logic
    public class CustomMaskFunction implements MaskFunction {
        @Override
        public String mask(String value) {
            // Example: Replace all digits with asterisks
            return value.replaceAll("[0-9]", "*");
        }
    }
    
    // 2. Apply the custom mask to a VO field
    @Data
    public class CardVO implements Serializable {
        @Masked(type = MaskType.CUSTOM_MASK, start = 0, end = value.length(), symbol = "#")
        private String cardNumber;
    }
  8. Implement database field encryption and decryption

    To automatically encrypt data when saving to the database and decrypt it when reading, add the @SecurityField annotation to the fields in your Entity/DO class. This works automatically with MyBatis and MyBatis Plus mappers.
    @Data
    @TableName(value ="user")
    public class UserDO implements Serializable {
        @TableId(value = "id", type = IdType.AUTO)
        private Long id;
    
        @TableField(value = "name")
        @SecurityField
        private String name;
    
        @TableField(value = "phone")
        @SecurityField
        private String phone;
    }
    
    // Usage in Service
    @Service
    public class UserService {
        @Autowired
        private UserMapper userMapper;
    
        public void saveUser(UserDO user) {
            userMapper.insert(user); // Automatically encrypts @SecurityField fields
        }
    
        public UserDO getUser(Long id) {
            return userMapper.selectById(id); // Automatically decrypts @SecurityField fields
        }
    }
  9. Prevent duplicate encryption of data

    The component uses a specific prefix to identify fields that have already been encrypted. This prevents the system from encrypting the same data multiple times, ensuring data consistency even when the same object reference is updated and saved repeatedly.
    public void testDuplicateEncryptionCheck() {
        UserInfoDO user = new UserInfoDO();
        user.setName("张三");
    
        // First encryption
        userService.saveUser(user);
    
        // Modify the same object reference and update again
        user.setName("李四");
        userService.updateUser(user); // Encrypts normally without duplicating existing encryption
    }
  10. Understand the data desensitization workflow

    The data desensitization process follows this flow:

    1. A Controller method annotated with @Desensitizationed returns an object.
    2. DesensitizationAspect intercepts the return and calls MaskAnnotationResolver.processObjectAndMask.
    3. The resolver recursively processes the object to handle:
      • Field-level masking via Masked annotations and MaskFunction.
      • Collection masking (supporting List and Map types).
      • Nested object masking via NestedMasked annotations.
  11. Implement data desensitization using @Desensitizationed and @Masked

    To desensitize data in API responses, use a two-tier annotation approach: first, mark the Controller method with @Desensitizationed to enable the desensitization aspect for that request. Then, mark specific fields in the return object (VO) with @Masked to define how that field should be masked. The @Masked annotation supports various MaskType values (e.g., NAME_MASK, PHONE_MASK, EMAIL_MASK) and allows custom configuration of start/end positions and masking symbols.
    // 1. Mark the controller method
    @PostMapping("/user")
    @Desensitizationed
    public UserVO getUser() {
        return userService.getUser();
    }
    
    // 2. Mark the fields in the VO
    @Data
    public class UserVO implements Serializable {
        @Masked(type = MaskType.NAME_MASK)
        private String name;
    
        @Masked(type = MaskType.CUSTOM_MASK, start = 2, end = 5, symbol = "#")
        private String customField;
    }
  12. Implement data desensitization (masking)

    To mask sensitive data in API responses, use the @Masked annotation on the fields of your VO (Value Object) and the @Desensitizationed annotation on the controller method. The MaskType determines the masking rule (e.g., NAME_MASK, PHONE_MASK).
    @Data
    public class UserVO implements Serializable {
        @Masked(type = MaskType.NAME_MASK)
        private String name;
    
        @Masked(type = MaskType.PHONE_MASK)
        private String phone;
    
        @Masked(type = MaskType.CUSTOM_MASK, start = 2, end = 5, symbol = "#")
        private String customField;
    }
    
    @RestController
    @RequestMapping("/api")
    public class UserController {
        @PostMapping("/user")
        @Desensitizationed
        public UserVO getUser() {
            // ... return UserVO object
        }
    }