JMaskify is an open-source Java library designed to safeguard sensitive data with versatile and customizable masking techniques. Whether your application handles personal, financial, or confidential information, JMaskify ensures its security through intuitive APIs and advanced masking strategies.
- Versatile Masking: Supports fixed-length anonymization, Base64 encoding, Debit/Credit Card Numbers, JSON, and multiline text masking.
- Flexible API: Easily adaptable for use cases involving JSON structures and multiline text.
- Open Source: MIT-licensed to encourage collaboration and transparency.
If you find JMaskify useful for your projects, consider supporting its development:
Your support helps ensure that JMaskify continues to improve and remain available as an open-source tool.
To work with JMaskify, ensure the following tools and dependencies are installed:
- JDK: Version 17 or higher
- Build Tool: Maven or Gradle
JMaskify leverages the following key libraries:
- Jackson: JSON processing (
jackson-databind) - Apache Commons Codec: Encoding utilities
- SLF4J: Logging framework
JMaskify is available on Maven Central. Add the dependency to your project:
<dependency>
<groupId>io.github.ehayik</groupId>
<artifactId>jmaskify</artifactId>
<version>1.0.1</version>
</dependency>This includes jackson-core and jackson-databind for JSON processing.
All dependencies and versions are managed in the project's pom.xml
The quickest way to mask sensitive data:
// Mask a credit card number
var creditCardNumber = "4289-3874-8064-8976";
var masked = Masker.creditCard().apply(creditCardNumber);
// Result: "****-****-****-8976"
// Mask an email address
var email = "john.doe@example.com";
var maskedEmail = Masker.fixedLength().apply(email);
// Result: "****************"For masking fields within JSON objects:
String json = """
{
"name": "John Doe",
"age": 30,
"contactInfo": {
"email": "john.doe@example.com",
"phone": "123-456-7890"
},
"creditCard": "1234-5678-9012-3456"
}
""";
// Create a JsonMasker instance
var masker = Masker.json()
.prettify(true)
.withProperty("email") // Default fixed pattern masking
.withProperty("phone", Masker.base64())
.withProperty("creditCard", Masker.creditCard('X'))
.withProperty("name", Masker.delegate(value -> "■■■■■■"));
// Apply masking
var maskedJson = masker.apply(json);
/*
Result: {
"name": "■■■■■■",
"age": 30,
"contactInfo": {
"email": "***************",
"phone": "MTIzLTQ1Ni03ODkw"
},
"creditCard": "XXXX-XXXX-XXXX-3456"
}
*/NOTE: Non-string values (numbers, booleans, nulls) are preserved without masking.
JMaskify provides powerful capabilities for masking string values within JSON arrays. Here are examples of different array masking scenarios:
When you need to mask an array of sensitive string values, such as credit card numbers:
String json = """
{
"name": "John Doe",
"creditCards": [
"1234-5678-9012-3456",
"4289-3874-8064-8976"
]
}
""";
var masker = JsonMasker.builder()
.withProperty("creditCards", Masker.creditCard('X'))
.build();
var maskedJson = masker.apply(json);
/* Result:
{
"name": "John Doe",
"creditCards": [
"XXXX-XXXX-XXXX-3456",
"XXXX-XXXX-XXXX-8976"
]
}
*/JMaskify can handle arrays containing a mix of different value types, masking only the string values:
String json = """
{
"name": "John Doe",
"mixedArray": [
"sensitive-string-data",
42,
true,
null,
{"nestedKey": "nestedValue"},
["nested", "array"]
]
}
""";
var masker = JsonMasker.builder()
.withProperty("mixedArray", Masker.fixedLength())
.build();
var maskedJson = masker.apply(json);
/* Result:
{
"name": "John Doe",
"mixedArray": [
"*********************",
42,
true,
null,
{"nestedKey": "***********"},
["******", "*****"]
]
}
*/JMaskify handles nested arrays with specific masking behavior:
String json = """
{
"name": "John Doe",
"nestedArrays": [
["sensitive-outer-inner", "another-value"],
42,
["not-masked-1", "not-masked-2"]
]
}
""";
var masker = JsonMasker.builder()
.withProperty("nestedArrays", Masker.fixedLength())
.build();
var maskedJson = masker.apply(json);
/* Result:
{
"name": "John Doe",
"nestedArrays": [
["*********************", "*************"],
42,
["************", "************"]
]
}
*/NOTE: This example demonstrates how JMaskify recursively processes nested arrays. All string values within nested arrays are masked consistently, regardless of their position or nesting level.
When working with log files or other text that spans multiple lines, you can use multiline text masking to identify and mask patterns:
String logContent = """
2023-05-15 INFO User john.doe@example.com logged in
2023-05-15 INFO IP Address: 192.168.1.1
""";
// Create a MultilinePatternMasker instance
var masker = Masker.multilinePattern()
.withMaskPattern("(\\d+\\.\\d+\\.\\d+\\.\\d+)");
// Apply masking
var maskedContent = masker.apply(logContent);
// Result:
// 2023-05-15 INFO User john.doe@example.com logged in
// 2023-05-15 INFO IP Address: **********Once you're comfortable with the basic masking operations, JMaskify offers more sophisticated features to handle complex masking requirements.
Create your own masking strategies for specialized requirements:
var masker = Masker.delegate((String input) -> {
if (input == null || input.length() <= 2) {
return input;
}
var first = input.charAt(0);
var last = input.charAt(input.length() - 1);
return first +
"*".repeat(input.length() - 2) +
last;
});
var maskedName = masker.apply("Johnson");
// Result: "J*****n"For complex scenarios, combine different masking approaches:
var json = """
{
"name": "John Doe",
"logs": [
"2023-05-15 INFO User john.doe@example.com logged in",
"2023-05-15 INFO IP Address: 192.168.1.1"
]
}
""";
var jsonMasker = Masker.json()
.withProperty("name", Masker.delegate(value -> "■■■■■■"))
.build();
var multilineMasker = Masker.multilinePattern()
.withMaskPattern("(\\d+\\.\\d+\\.\\d+\\.\\d+)")
.build();
var maskedContent = jsonMasker
.andThen(multilineMasker)
.andThen(Masker.base64())
.apply(json);
// Result applies all masking strategies in sequenceJMaskify uses the SLF4J logging facade, allowing integration with popular logging frameworks
such as Logback, Log4j,
tinylog , or Java Utils Logging.
Refer to your logging framework's documentation to set the DEBUG log level for the package io.github.ehayik.jmaskify.
Add the following configuration to your logback.xml file to enable debug logs:
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="io.github.ehayik.jmaskify" level="DEBUG" />
</configuration>JMaskify provides robust handling for invalid inputs. For instance, attempting to mask invalid JSON results in exceptions with clear error messages:
// Create a masker for email fields
var masker = Masker.json().withProperty("email").build();
// When applying to invalid JSON, a MaskingException will be thrown
// with the message "Failed to mask JSON content"
// masker.apply("///"); // This would throw MaskingExceptionIf you found a bug or a missing feature—you're very welcome to submit an issue and a pull request with a fix.
This project is licensed under the MIT License.
