houbb/sensitive

repository·master·Indexed 20 days ago

https://github.com/houbb/sensitive

A high-performance Java library for log masking and sensitive data obfuscation using annotations. It supports deep copying of objects, generating masked JSON via FastJSON2, and provides plugins for Logback and Log4j2. The library includes built-in strategies for masking phone numbers, emails, passwords, and IDs, and allows for custom IStrategy and ICondition implementations.

Tokens
17.7K
Snippets
50
Records
69
Agent score
71%

What's inside houbb-sensitive

  1. Key advantages of the chars-scan integration design

    master

    The integration design for chars-scan provides several benefits for developers implementing sensitive data masking:

    • Unified Configuration Management: Both log4j2 and logback share the same configuration set, preventing duplication.
    • High Extensibility: Supports custom scanning rules (identification) and custom replacement rules (masking logic), including the ability to override built-in strategies.
    • Zero Intrusion: Integrates with the existing chars-scan library without requiring modifications to its source code.
    • Performance Optimization: Uses a Singleton pattern to manage CharsScanBs and supports multiple core implementations such as defaults, concurrency, and threadLocal.
    • Ease of Use: Driven by configuration files and uses reflection to load custom strategies, requiring no code changes to update logic.
  2. Use extracted built-in desensitization utility methods

    master
    The project provides built-in desensitization methods that have been extracted into standalone utility class methods. This allows you to call specific desensitization logic directly without needing to manage complex configurations or full serialization flows.
  3. How custom strategy priority works

    master

    The EnhancedSensitiveScanner uses the chars.scan.custom.priority setting to decide the order of operations:

    1. higher (Default): Custom strategies are applied to the original text first. After custom masking is complete, the native chars-scan logic is applied to the result, skipping segments already processed by custom rules.
    2. native: The native chars-scan logic is applied first. Custom strategies are then applied only to parts of the text that were not modified by the native scanner (i.e., segments that do not contain the masking character *).
  4. Use @Sensitive and @SensitiveEntry annotations

    master

    The project provides annotations to mark sensitive data for masking during deep copying or JSON serialization.

    • @Sensitive: The core annotation used to mark a field as sensitive.
    • @SensitiveEntry: Used to mark an entry point for sensitive data processing, allowing for custom configuration of how the entry is handled.

    These annotations allow you to define which fields should be masked when an object is processed by the library's utility methods.

  5. Understand the CharsScanBs core architecture

    master

    The CharsScanBs framework is organized into several specialized components that manage the lifecycle of sensitive data scanning and masking. The architecture consists of:

    • CharsScanBs: The main entry point/guiding class.
    • charsScanFactory: Manages scanning strategy rules (what to identify).
    • charsReplaceFactory: Manages replacement/masking logic (how to mask).
    • charsReplaceHash: Controls whether a hash value is displayed.
    • prefixCharSet: Defines the set of prefix characters that trigger scanning.
    • whiteListTrie: A prefix tree used to manage whitelist rules to skip specific patterns.
    • charsCore: Handles core implementation details, such as concurrency safety.
  6. Handle nested objects and collections with @SensitiveEntry

    master

    To perform masking on nested structures, use the @SensitiveEntry annotation. This enables cascading masking:

    • On a Collection of simple types: It iterates through the collection and applies masking to the elements (if they are annotated).
    • On an Object field: It processes the masking annotations within that object's fields.
    • On a Collection of Objects: It iterates through each object in the collection and processes their internal masking annotations.

    Example of a collection of strings or arrays:

    public class UserEntryBaseType {
        @SensitiveEntry
        @Sensitive(strategy = StrategyChineseName.class)
        private List<String> chineseNameList;
    
        @SensitiveEntry
        @Sensitive(strategy = StrategyChineseName.class)
        private String[] chineseNameArray;
    }
    public class UserEntryObject {
        @SensitiveEntry
        private User user;
    
        @SensitiveEntry
        private List<User> userList;
    
        @SensitiveEntry
        private User[] userArray;
    }
  7. Best practices and precautions for custom strategies

    master

    When implementing and using custom sensitive data strategies, consider the following:

    • Performance: Custom strategies use regular expressions; adding many complex patterns will increase the overhead of regex matching during scanning.
    • Conflict Management: Ensure your custom regexPattern does not conflict with existing built-in strategies to avoid unexpected masking behavior.
    • Testing: Always perform thorough unit testing on your desensitize logic and regex accuracy before deployment.
    • Strategy IDs: Use unique IDs to avoid collisions. For reference, common IDs include 1 for phone numbers, 2 for ID cards, 3 for bank cards, 4 for emails, and 5 for names.
  8. Integrate with log4j2

    master

    To enable log masking in log4j2, add the sensitive-log4j2 dependency and configure your log4j2.xml to use SensitivePatternLayout. Ensure log4j-api and log4j-core are also present in your project.

    Note: SensitiveRewritePolicy is deprecated and should not be used in new projects.

    <dependency>
        <groupId>com.github.houbb</groupId>
        <artifactId>sensitive-log4j2</artifactId>
        <version>1.9.1</version>
    </dependency>
    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN" packages="com.github.houbb.sensitive.log4j2.layout">
        <Properties>
            <Property name="PATTERN">%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>
        </Properties>
        <Appenders>
            <Console name="Console" target="SYSTEM_OUT">
                <SensitivePatternLayout pattern="${PATTERN}" charset="UTF-8"/>
            </Console>
        </Appenders>
        <Loggers>
            <Root level="INFO">
                <AppenderRef ref="Console"/>
            </Root>
        </Loggers>
    </Configuration>
  9. Integrate sensitive-log4j2 via Maven

    master

    To enable automatic log masking using Log4j2, add the sensitive-log4j2 dependency to your project. Ensure you also have the standard log4j-api and log4j-core dependencies present.

    <dependency>
        <groupId>com.github.houbb</groupId>
        <artifactId>sensitive-log4j2</artifactId>
        <version>1.2.1</version>
    </dependency>
    
    <!-- Ensure log4j2 core/api are also present -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>${log4j2.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>${log4j2.version}</version>
    </dependency>
  10. Integrate desensitization into Log4j/Logback Layouts

    master

    To automatically desensitize log messages, override the toSerializable(LogEvent event) method in your custom PatternLayout. Use EnhancedSensitiveScanner.scanAndReplace(text) on the formatted log string to ensure all sensitive data is masked before it is written to the logs.

    @Override
    public String toSerializable(LogEvent event) {
        StringBuilder stringBuilder = new StringBuilder();
        for(PatternFormatter formatter : patternFormatterList) {
            formatter.format(event, stringBuilder);
        }
        String text = stringBuilder.toString();
        
        try {
            // 使用增强的扫描处理器
            return EnhancedSensitiveScanner.scanAndReplace(text);
        } catch (Exception e) {
            return text;
        }
    }