Category Archives: Mask

Mask Zipcode/Pincode/Postal Code on Web Page


A lot of information that you share freely, such as your date of birth, phone number, ZIP code and email address, are very valuable to criminals. Think of how many accounts require you to verify your identity by entering in your birthday or your ZIP code before making a transaction.

Alone, your ZIP code might not be of much value all by itself, but criminals will take that information and post it on underground sites where they buy, sell and trade bunches of personal information. From those sites, criminals can purchase enough of your personal information to use it for fraud

See Also :

CVV Masking Example

Here considering, Pincode of length 5 digits. By masking will hide all 5 digits. For example, my pincode is 75038 than after mask will display as XXXXX. Pincode for some card can also be as six digit take this as assignment and make code changes accordingly so that support for both five and six digits.

original zipcode masked zipcode

Note :

This masking example is created considering standard length of text size and formatting of text field, that can vary according to organizations. If your organization having different format and text size modify source code according to your need. If you are facing any issue drop a comments will try to connect as soon as possible.

Download Source code

To download the source code of this example, click on below given download link.

Mask Pincode

Drop me your questions in comments section.

References

Advertisements

Mask Passport On Web Page


The passport serves as proof of your identity and your nationality which itself can be advantageous depending on your destination. As such, you should prioritize its security above all else when you travel overseas.

See Also :

Consequences of Passport Number Identity Theft

Under no circumstances should you disclose any sensitive information regarding yourself, passport number included. It may just be a jumble of digits but it’s a very valuable commodity for criminals if they even get their hands on it.
There are lots of consequences of passport identity theft as below:

  • A criminal could easily manufacture a passport with passport number, full legal name , date of birth and another person’s picture on it. This may not get them into the US (easily) but it could conceivable get them to a country nearby and then from there they could travel to the US or travel on others countries.
  • Criminal all over the world can use others stolen passport to commit a crime or do anything on others name.
  • The passport is use as an identity official documents if you don’t have driving license. Think about if someone using fraud passport and make some accident on road.
  • The fraud passport with your personal information full legal name, date of birth (available in facebook) , another person picture and address used to impersonate you. This fraud passport can be used as identity proof to open and access your credit / debit cards, social security, email, medical records, your character, your tax records.
  • A lot of passports have a chip too, which stores all your personal data.

Passport Masking Example

Here considering, Passport of length 8 digits. By masking will hide initial 4 digits. For example, my passport number is A1234765 than after mask will display as XXXX4765. Passport for some card can also be vary as per county take this as assignment and make code changes accordingly so that support for both 8 and more digits.

Original passport mask passport

Note :
This masking example is created considering standard length of text size and formatting of text field, that can vary according to organizations. If your organization having different format and text size modify source code according to your need. If you are facing any issue drop a comments will try to connect as soon as possible.

Download Source code


To download the source code of this example, click on below given download link.

Mask Passport

Drop me your questions in comments section.

References

Mask Aadhar Number On Page


What is Aadhaar?

Aadhaar is a verifiable 12-digit identification number issued by UIDAI (“Authority”) to the resident of India for free of cost after satisfying the verification process laid down by the Authority.
Any individual, irrespective of age and gender, who is a resident of India, may voluntarily enrol to obtain Aadhaar number based on demographic and biometric information.

What is Masked Aadhaar?

Aadhar number is very senstive information by which we can track an individual complete information thats why UIDAI provide both the options for down load Aadhar card.

1) Regular Aadhar Card : All digits visible
2) Masked Aadhar Card : Replacing of first 8 digits of Aadhaar number with some characters like “xxxx-xxxx” while only last 4 digits of the Aadhaar Number are visible.

How to Mask Aadhaar in your web page?

Making aadhar number Replacing of first 8 digits of Aadhaar number with some characters like “xxxx-xxxx” while only last 4 digits of the Aadhaar Number are visible. In web page
aadhar number text box when user click/focus or hover on text box will display regular aadahr number otherwise will display as masked.

See Also :

Mask Aadhar Number Example

how to mask aadhar number on web page masked aadhar number on page

HTML Changes

Create a text box on your page with below html.

Aadhar Number: 

Java Script/JQuery Changes

Copy below java script in your head section of page.


var originalVal;
$(document).ready(function()
{
       if($('#txtAadhar').val().length>0)
		 {
		 if($('#txtAadhar').val().indexOf("X")==-1)
			{
			  originalVal=$('#txtAadhar').val();
			}
		    maskAadhar(this);
		 }

	    $('#txtAadhar').blur( function(e)
		{
	    	if($('#txtAadhar').val().indexOf("X")==-1)
	    	{
	    	  originalVal=$('#txtAadhar').val();
	    	}
	    	 maskAadhar(this);
		});

		$('#txtAadhar').focus( function(e)
		{
			$(this).val(originalVal);
		});
});
function maskAadhar(regularAadhar)
{
	 var varlen =$(regularAadhar).val().length;
	 if(varlen > 12)
	 {
	 $("#error").text('Not Valid Aadhar Number.');
	 }
	 else
	 {
	 $("#error").text('');
	 var str = $(regularAadhar).val();

	 var mask = varlen > 0 ? varlen > 1 ? varlen > 2 ? varlen > 3 ? varlen > 4 ? varlen > 5  ? varlen > 6 ? varlen > 7 ?
	        'XXXX XXXX'
          : 'XXXX XXX'
          : 'XXXX XX'
          : 'XXXX X'
          : 'XXXX'
		  : 'XXX'
		  : 'XX'
		  : 'X'
          : '';
          if (varlen < 9) {
          $(regularAadhar).val(mask);
          } else {
          $(regularAadhar).val(mask +' '+ $(regularAadhar).val().substring(8));
          }
   }
}

Download Source code

To download the source code of this example, click on below given download link.

Mask Aadhar Card

Drop me your questions in comments section.

References

https://www.uidai.gov.in/my-aadhaar/about-your-aadhaar.html
https://www.uidai.gov.in/283-faqs/aadhaar-online-services/e-aadhaar/1887-what-is-masked-aadhaar.html

Log4j2: How to Mask Logs Personal/Confidential/SPI Information


You can configure Log4j2 LogEventConverter plugin for masking personal/ confidential/ SPI data. For example here we are masking credit card number, SSN and CVV of log statements.

Below Log4j2 dependencies you need to add with your application.

Pre-Requisite

Log4j2 Dependency

pom.xml entry


         <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.6.1</version>
        </dependency>
   

Log4j2.xml Configuration File

Below is basic console based configuration for masking where packages used for where loggers need to apply and masking plugin annotation as in below program. In PatternLayout used key as spi which is map with plugin which will mask log text and print as message.


<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns="http://logging.apache.org/log4j/2.0/config"
       status="OFF" packages="com.mask.logs">
       <Appenders>
    <Console name="STDOUT" target="SYSTEM_OUT">
     <PatternLayout pattern="%d{yyyyMMdd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %spi%n"/>
   
    </Console>
  </Appenders>
  <loggers>
              <Logger name="org.apache.log4j.xml" level="all" />
              <root level="all">
                     <appender-ref ref="STDOUT" level="TRACE" />
                     </root>
  </loggers>
</configuration>

To know more about log4j2 configuration follow below link:

Log4j2 Java Logging Example Tutorial – XML Configuration, Severity Levels, Formatting and Appenders

Log4j2 Plugin Code for Masking

Created this LogMakingConverter Plug in for masking logs statement
Here masking for Credit card number, CVV and SSN . You can also implement for password and rest depend on your application needs. Here we have used Java regular expression Mater and Pattern apis for maskin and also different character as +++ for CVV,********* for SSN and **************** for credit card by matching number of digits in log lines.

package com.mask.logs;
/**
 * Created this LogMakingConverter Plug in for masking logs statement
 * Here masking for Credit card number, CVV and SSN .
 * You can also implement for password and rest depend on your application needs.
 */
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.pattern.ConverterKeys;
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;

@Plugin(name="LogMaskingConverter", category = "Converter")
@ConverterKeys({"spi","trscId"})
public class LogMaskingConverter extends LogEventPatternConverter{
	private static final String CREDIT_CARD_REGEX = "([0-9]{16})";;
	private static final Pattern CREDIT_CARD_PATTERN = Pattern.compile(CREDIT_CARD_REGEX);
	private static final String CAREDIT_CARD_REPLACEMENT_REGEX = "XXXXXXXXXXXXXXXX";

	private static final String CVV_REGEX = "([0-9]{3})";
	private static final Pattern CVV_PATTERN = Pattern.compile(CVV_REGEX);
	private static final String CVV_REPLACEMENT_REGEX = "+++";

	private static final String SSN_REGEX = "([0-9]{9})";
	private static final Pattern SSN_PATTERN = Pattern.compile(SSN_REGEX);
	private static final String SSN_REPLACEMENT_REGEX = "*********";

    protected LogMaskingConverter(String name, String style) {
        super(name, style);
    }

    public static LogMaskingConverter newInstance(String[] options) {
        return new LogMaskingConverter("spi",Thread.currentThread().getName());
    }

    @Override
    public void format(LogEvent event, StringBuilder outputMessage) {
    	String message = event.getMessage().getFormattedMessage();
		String maskedMessage = message;
		try {
			maskedMessage = mask(message);
		} catch (Exception e) {
			System.out.println("Failed While Masking");
			maskedMessage = message;
		}
		outputMessage.append(maskedMessage);	

    }

    private String mask(String message) {
    	Matcher matcher =null;
		StringBuffer buffer = new StringBuffer();

		matcher = CREDIT_CARD_PATTERN.matcher(message);
		maskMatcher(matcher, buffer,CAREDIT_CARD_REPLACEMENT_REGEX);
		message=buffer.toString();
		buffer.setLength(0);

		matcher = SSN_PATTERN.matcher(message);
		maskMatcher(matcher, buffer,SSN_REPLACEMENT_REGEX);
		message=buffer.toString();
		buffer.setLength(0);

		matcher = CVV_PATTERN.matcher(message);
		maskMatcher(matcher, buffer,CVV_REPLACEMENT_REGEX);

		return buffer.toString();
	}

    private StringBuffer maskMatcher(Matcher matcher, StringBuffer buffer, String maskStr)
    {
    	while (matcher.find()) {
			matcher.appendReplacement(buffer,maskStr);
		}
		matcher.appendTail(buffer);
    	return buffer;
    }

}

Masking Test Program

Below is test program to print some log statements which are converting by Log4j2.

package com.mask.logs;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class MaskingTest {
	  private static final Logger logger = LogManager.getLogger(MaskingTest.class);
      public static void myTest(){
             logger.info("this is my info message");
             logger.debug("This is debug message");
             logger.debug("Passed to server::0084USER:17603,IP:0:0:0:0:0:0:0:1,3425,Credit Card 1:1000002367844224,3425,Credit Card2:1000002367844224 , CVV:234,SSN:123456789");

      }
      public static void main(String[] args) {
             myTest();
      }
}

Output

Below is mask logs by log4j2 for confidential/personal/spi data.

20180607 11:20:43.558 [main] INFO  com.mask.logs.MaskingTest - this is my info message
20180607 11:20:43.559 [main] DEBUG com.mask.logs.MaskingTest - This is debug message
20180607 11:20:43.560 [main] DEBUG com.mask.logs.MaskingTest - Passed to server::+++4USER:+++03,IP:0:0:0:0:0:0:0:1,+++5,Credit Card 1:XXXXXXXXXXXXXXXX,+++5,Credit Card2:XXXXXXXXXXXXXXXX , CVV:+++,SSN:
*********

Summary

  • Step by step program for masking sensitive information in logs.
  • Log4j2 XML Configuration for loggers and appenders for masking.
  • LogMaskingConverter Log4j2 plugin for masking log statements.
  • Regular expression for Creditcard, SSN and CVV.
  • Test program to write logs  by java logging api to write in logs file.

More 

Below are some more masking ways for different type of data like XML, JSON and printing objects before logging , sending to page or transferring over network.

How to MASK XML Confidential/Personal Data : JAVA


Here you will see all steps to mask confidential/ information in XML like credit card, CVV, Exp date,  SSN, password etc. So that it will print in mask form as ****** so that unauthorize use will not misuse of others information.

Pre- Requisite

Use below library or add in pom.xml.


<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.10.2</version>
</dependency>

Here is same XML file as AccountDetail.xml where need to mask cardNumber, cvv and expDate .



<AccountList>
    <Account>
        <id>E001</id>
        <FirstName>Saurabh</FirstName>
        <LastName>Gupta</LastName>
        <AddressDetail>
            <AddressLine1>Noida City Center</AddressLine1>
            <City>Noida</City>
            <State>UP</State>
            <Pincode>201301</Pincode>
            <Contry>India</Contry>
        </AddressDetail>
        <CreditCardDetail>
            <CardNumber>1233454565676567</CardNumber>
            <CVV>456</CVV>
            <ExpDate>12/90</ExpDate>
        </CreditCardDetail>
    </Account>
    <Account>
        <id>E002</id>
        <FirstName>Ankur</FirstName>
        <LastName>Mehrotra</LastName>
        <AddressDetail>
            <AddressLine1>New Delhi Metro Station</AddressLine1>
            <City>New Delhi</City>
            <State>UP</State>
            <Pincode>210345</Pincode>
            <Contry>India</Contry>
        </AddressDetail>
        <CreditCardDetail>
            <CardNumber>8967452312123456</CardNumber>
            <CVV>876</CVV>
            <ExpDate>09/83</ExpDate>
        </CreditCardDetail>
    </Account>
    <Account>
        <id>E003</id>
        <FirstName>Shailesh</FirstName>
        <LastName>Nagar</LastName>
        <AddressDetail>
            <AddressLine1>Dwarka Metro Station</AddressLine1>
            <City>Delhi</City>
            <State>Delhi</State>
            <Pincode>345876</Pincode>
            <Contry>India</Contry>
        </AddressDetail>
        <CreditCardDetail>
            <CardNumber>9078563412345678</CardNumber>
            <CVV>986</CVV>
            <ExpDate>08/99</ExpDate>
        </CreditCardDetail>
    </Account>
</AccountList>

Java code to mask above XML. In below code cardNumber is masking partially so that show last four digits only and hide rest of numbers while cvv and exp date digits are masked completely.

package com.mask.xml;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;

public class MaskXML {

	public static void main(String[] args) {

		try {
			FileInputStream inputStream = new FileInputStream(
					new File("D:\\Saurabh Gupta\\Workspace\\JavaTestExamples\\src\\main\\resources\\UserAccountDetail.xml"));
			Document doc = Jsoup.parse(inputStream, "UTF-8", "", Parser.xmlParser());
			Elements toMaskTagCompletely = doc.select("Pincode,ExpDate,CVV");
			Elements toMaskTagPartially = doc.select("CardNumber");
			for (Element element : toMaskTagCompletely) {
				element.text(replaceDigits(element.text()));
			}
			for (Element element : toMaskTagPartially) {
				element.text("XXXXXXXXXXXX" + element.text().substring(element.text().length() - 4));
			}
			System.out.println(doc.toString());
		} catch (FileNotFoundException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		}

	}

	private static String replaceDigits(String text) {
		StringBuffer buffer = new StringBuffer(text.length());
		Pattern pattern = Pattern.compile("\\d");
		Matcher matcher = pattern.matcher(text);
		while (matcher.find()) {
			matcher.appendReplacement(buffer, "X");
		}
		return buffer.toString();
	}

}

Result : Masked XML


<?xml version="1.0" encoding="UTF-8"?> 
<AccountList> 
 <Account> 
  <id>
   E001
  </id> 
  <FirstName>
   Saurabh
  </FirstName> 
  <LastName>
   Gupta
  </LastName> 
  <AddressDetail> 
   <AddressLine1>
    Noida City Center
   </AddressLine1> 
   <City>
    Noida
   </City> 
   <State>
    UP
   </State> 
   <Pincode>
    XXXXXX
   </Pincode> 
   <Contry>
    India
   </Contry> 
  </AddressDetail> 
  <CreditCardDetail> 
   <CardNumber>
    XXXXXXXXXXXX6567
   </CardNumber> 
   <CVV>
    XXX
   </CVV> 
   <ExpDate>
    XX/XX
   </ExpDate> 
  </CreditCardDetail> 
 </Account> 
 <Account> 
  <id>
   E002
  </id> 
  <FirstName>
   Ankur
  </FirstName> 
  <LastName>
   Mehrotra
  </LastName> 
  <AddressDetail> 
   <AddressLine1>
    New Delhi Metro Station
   </AddressLine1> 
   <City>
    New Delhi
   </City> 
   <State>
    UP
   </State> 
   <Pincode>
    XXXXXX
   </Pincode> 
   <Contry>
    India
   </Contry> 
  </AddressDetail> 
  <CreditCardDetail> 
   <CardNumber>
    XXXXXXXXXXXX3456
   </CardNumber> 
   <CVV>
    XXX
   </CVV> 
   <ExpDate>
    XX/XX
   </ExpDate> 
  </CreditCardDetail> 
 </Account> 
 <Account> 
  <id>
   E003
  </id> 
  <FirstName>
   Shailesh
  </FirstName> 
  <LastName>
   Nagar
  </LastName> 
  <AddressDetail> 
   <AddressLine1>
    Dwarka Metro Station
   </AddressLine1> 
   <City>
    Delhi
   </City> 
   <State>
    Delhi
   </State> 
   <Pincode>
    XXXXXX
   </Pincode> 
   <Contry>
    India
   </Contry> 
  </AddressDetail> 
  <CreditCardDetail> 
   <CardNumber>
    XXXXXXXXXXXX5678
   </CardNumber> 
   <CVV>
    XXX
   </CVV> 
   <ExpDate>
    XX/XX
   </ExpDate> 
  </CreditCardDetail> 
 </Account> 
</AccountList>

Summary

  • Example for mask XML.
  • Shared API and source code for masking XML in less code.
  • Shared code for Mask complete and partial text data for credit card, SSN, CVV etc.

Related Posts

Below are some more masking ways for different type of data like XML, JSON and printing objects before logging , sending to page or transferring over network.

Log4j2: How to Mask Logs Personal/Confidential/SPI Information

How to Mask JSON Confidential/Personal Information in logs :JAVA

How to mask JAVA Object confidential/personal information in logs while Printing

 

How to Mask JSON Confidential/Personal Information in logs :JAVA


Here you will see all steps to mask confidential/ information like credit card, CVV, Exp date,  SSN, password etc. So that it will print in mask form as ****** so that unauthorize use will not misuse of others information.

Here using Google GSON and GsonBuilder converting Java object to JSON and again converting JSON to Java Object.

By using Java refelection api’s replacing SPI fields data with *******.

Input JSON File AccountDetail


{
  "firstName": "Saurabh",
  "lastName": "Gupta",
  "address": {
    "addressLine1": "Noida City Center",
    "city": "Noida",
    "state": "UP",
    "pincode": "India",
    "country": "20310"
  },
  "creditCardDetail": {
    "cardNumber": "1234567890123456",
    "cvv": "123",
    "expDate": "12/90"
  }
}

 

Code to Mask JSON

package com.mask.json;

import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class MaskJSONTest {
	static Set fieldSet = new HashSet();
	static List fieldNames = Arrays.asList("cardNumber", "cvv", "expDate");

	public static void main(String[] args) throws IOException {
		StringBuilder contentBuilder = new StringBuilder();
		try (Stream stream = Files.lines(
				Paths.get(
						"D:\\Saurabh Gupta\\Workspace\\JavaTestExamples\\src\\main\\resources\\AccountDetail.json"),
				StandardCharsets.UTF_8)) {
			stream.forEach(s -&gt; contentBuilder.append(s).append("\n"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		//Create GSON object
		//apply NullSearialization and Pretty formatting by GSON Builder
		Gson gson = getJsonBuilder().create();
		AccountDetail accounDetail = gson.fromJson(contentBuilder.toString(), AccountDetail.class);
		mask(accounDetail);
		System.out.println(gson.toJson(accounDetail));
	}
	public static GsonBuilder getJsonBuilder()
	{
		GsonBuilder builder = new GsonBuilder();

		// Setting for formatted output and serialize null value
		builder.setPrettyPrinting().serializeNulls();

		return builder;
	}

	public static void mask(Object object) {
		try {
			Field[] fields = object.getClass().getDeclaredFields();
			Object value = null;
			for (int i = 0; i <span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>&lt; fields.length; i++) {
				fields[i].setAccessible(true);
				value = fields[i].get(object);
				if (value != null &amp;&amp; fieldSet.add(fields[i].getName())) {
					if (fields[i].getType().isArray()
							|| fields[i].getType().getCanonicalName().startsWith(&quot;com.mask.json&quot;)) {
						mask(value);
					} else {
						if (fieldNames.contains(fields[i].getName()) &amp;&amp; fields[i].get(object) != null) {
							fields[i].set(object, replaceDigits((String) fields[i].get(object)));
						}
					}
				}

			}
		} catch (IllegalAccessException ex) {
			ex.printStackTrace();
		}
	}

	private static String replaceDigits(String text) {
		StringBuffer buffer = new StringBuffer(text.length());
		Pattern pattern = Pattern.compile(&quot;\\d&quot;);
		Matcher matcher = pattern.matcher(text);
		while (matcher.find()) {
			matcher.appendReplacement(buffer, &quot;X&quot;);
		}
		return buffer.toString();
	}

}

Model Classes


package com.mask.json;

public class AccountDetail {
private String firstName;
private String lastName;
private AddressDetail address;
private CreditCardDetail creditCardDetail;
public AccountDetail(String firstName, String lastName, AddressDetail address, CreditCardDetail creditCardDetail) {
	super();
	this.firstName = firstName;
	this.lastName = lastName;
	this.address = address;
	this.creditCardDetail = creditCardDetail;
}
public String getFirstName() {
	return firstName;
}
public void setFirstName(String firstName) {
	this.firstName = firstName;
}
public String getLastName() {
	return lastName;
}
public void setLastName(String lastName) {
	this.lastName = lastName;
}
public AddressDetail getAddress() {
	return address;
}
public void setAddress(AddressDetail address) {
	this.address = address;
}
public CreditCardDetail getCreditCardDetail() {
	return creditCardDetail;
}
public void setCreditCardDetail(CreditCardDetail creditCardDetail) {
	this.creditCardDetail = creditCardDetail;
}

}


package com.mask.json;

public class AddressDetail {

private String addressLine1;
private String city;
private String state;
private String pincode;
private String country;

public AddressDetail(String addressLine1, String city, String state, String pincode, String country) {
	super();
	this.addressLine1 = addressLine1;
	this.city = city;
	this.state = state;
	this.pincode = pincode;
	this.country = country;
}
public String getAddressLine1() {
	return addressLine1;
}
public void setAddressLine1(String addressLine1) {
	this.addressLine1 = addressLine1;
}
public String getCity() {
	return city;
}
public void setCity(String city) {
	this.city = city;
}
public String getState() {
	return state;
}
public void setState(String state) {
	this.state = state;
}
public String getPincode() {
	return pincode;
}
public void setPincode(String pincode) {
	this.pincode = pincode;
}
public String getCountry() {
	return country;
}
public void setCountry(String country) {
	this.country = country;
}

}

package com.mask.json;

public class CreditCardDetail{
private String cardNumber;
private String cvv;
private String expDate;

public CreditCardDetail(String cardNumber, String cvv, String expDate) {
	super();
	this.cardNumber = cardNumber;
	this.cvv = cvv;
	this.expDate = expDate;
}

public String getCardNumber() {
	return cardNumber;
}
public void setCardNumber(String cardNumber) {
	this.cardNumber = cardNumber;
}
public String getCvv() {
	return cvv;
}
public void setCvv(String cvv) {
	this.cvv = cvv;
}
public String getExpDate() {
	return expDate;
}
public void setExpDate(String expDate) {
	this.expDate = expDate;
}

}

Output Masked JSON :

{
“firstName”: “Saurabh”,
“lastName”: “Gupta”,
“address”: {
“addressLine1”: “Noida City Center”,
“city”: “Noida”,
“state”: “UP”,
“pincode”: “India”,
“country”: “20310”
},
“creditCardDetail”: {
“cardNumber”: “XXXXXXXXXXXXXXXX”,
“cvv”: “XXX”,
“expDate”: “XX/XX”
}
}

Related Posts

Below are some more masking ways for different type of data like XML, JSON and printing objects before logging , sending to page or transferring over network.

Log4j2: How to Mask Logs Personal/Confidential/SPI Information

How to MASK XML Confidential/Personal Data : JAVA

How to mask JAVA Object confidential/personal information in logs while Printing

How to mask JAVA Object confidential/personal information in logs while Printing


Here you will see all steps to mask confidential/ information like credit card, CVV, Exp date,  SSN, password etc. So that it will print in mask form as ****** so that unauthorize use will not misuse of others information.

Main concept to mask an Java for personal information by using reflection API and string override method by extending mask class.

Below are steps to masking Java Object :

  • Extends classes with MaskData class.
  • Override toString() method of object class and implement in MaskData Class.
  • Use JAVA reflection apis to get all fields objects and change SPI fields with *****.
  • Use replace digits methods method to replace digits with *.

Below are classes AccountDetail, Address and CredeitCard where only confidential information need to mask for Credit Card.

package com.model;

import com.mask.object.MaskData;

public class AccountDetail extends MaskData {
private String firstName;
private String lastName;
private AddressDetail address;
private CreditCardDetail creditCardDetail;
public AccountDetail(String firstName, String lastName, AddressDetail address, CreditCardDetail creditCardDetail) {
	super();
	this.firstName = firstName;
	this.lastName = lastName;
	this.address = address;
	this.creditCardDetail = creditCardDetail;
}
public String getFirstName() {
	return firstName;
}
public void setFirstName(String firstName) {
	this.firstName = firstName;
}
public String getLastName() {
	return lastName;
}
public void setLastName(String lastName) {
	this.lastName = lastName;
}
public AddressDetail getAddress() {
	return address;
}
public void setAddress(AddressDetail address) {
	this.address = address;
}
public CreditCardDetail getCreditCardDetail() {
	return creditCardDetail;
}
public void setCreditCardDetail(CreditCardDetail creditCardDetail) {
	this.creditCardDetail = creditCardDetail;
}

}

Address Class not having any confidential information.
package com.model;

import com.mask.object.MaskData;

public class AddressDetail extends MaskData{

private String addressLine1;
private String city;
private String state;
private String pincode;
private String country;

public AddressDetail(String addressLine1, String city, String state, String pincode, String country) {
	super();
	this.addressLine1 = addressLine1;
	this.city = city;
	this.state = state;
	this.pincode = pincode;
	this.country = country;
}
public String getAddressLine1() {
	return addressLine1;
}
public void setAddressLine1(String addressLine1) {
	this.addressLine1 = addressLine1;
}
public String getCity() {
	return city;
}
public void setCity(String city) {
	this.city = city;
}
public String getState() {
	return state;
}
public void setState(String state) {
	this.state = state;
}
public String getPincode() {
	return pincode;
}
public void setPincode(String pincode) {
	this.pincode = pincode;
}
public String getCountry() {
	return country;
}
public void setCountry(String country) {
	this.country = country;
}

}

CreditCardDetail class is having confidential fields cardNumber,cvv and expDate only these fields need to mask.

package com.model;

import com.mask.object.MaskData;

public class CreditCardDetail extends MaskData{
private String cardNumber;
private String cvv;
private String expDate;

public CreditCardDetail(String cardNumber, String cvv, String expDate) {
	super();
	this.cardNumber = cardNumber;
	this.cvv = cvv;
	this.expDate = expDate;
}

public String getCardNumber() {
	return cardNumber;
}
public void setCardNumber(String cardNumber) {
	this.cardNumber = cardNumber;
}
public String getCvv() {
	return cvv;
}
public void setCvv(String cvv) {
	this.cvv = cvv;
}
public String getExpDate() {
	return expDate;
}
public void setExpDate(String expDate) {
	this.expDate = expDate;
}

}

This is main class where masking these confidential fields by using JAVA reflection apis and override toString() method of Object Class.


package com.mask.object;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MaskData implements Cloneable {
	Set fieldSet=new HashSet();
	String[] spiData = { "cardNumber", "cvv", "expDate" };

	public Object clone() {
		return this;
	}

	@Override
	public String toString() {
		StringBuffer buffer=new StringBuffer();
		try
		{
		Object object=super.clone();
		printObjectStream(buffer,object);
		}
		 catch (CloneNotSupportedException ex)
		{
			 ex.printStackTrace();
		}
		return buffer.toString();
	}

	private void printObjectStream(StringBuffer buffer, Object object) {
		try {
			buffer.append(object.getClass().getCanonicalName()).append("[\n");
			Object value=null;
			for (Field field : object.getClass().getDeclaredFields()) {
				if(fieldSet.add(field.getName()))
				{
					field.setAccessible(true);
					//System.out.println(field.getName());
					buffer.append(field.getName() + "=");
					value = field.get(object);
					if(value!=null)
					{
						if(field.getType().isArray() |field.getType().getCanonicalName().startsWith("com.model"))
						{
							printObjectStream(buffer,value);
						}
						else if (Arrays.asList(spiData).contains(field.getName())) {
							//field.set(object, replaceDigits((String) field.get(object)));
							buffer.append(replaceDigits((String) value) );
						}
						else
						{
							buffer.append( value );
						}
					}
				}

				buffer.append("\n");
			}
			buffer.append("]");
		} catch (IllegalAccessException ex) {
			ex.printStackTrace();
		}

	}

	private String replaceDigits(String text) {
		StringBuffer buffer = new StringBuffer(text.length());
		Pattern pattern = Pattern.compile("\\d");
		Matcher matcher = pattern.matcher(text);
		while (matcher.find()) {
			matcher.appendReplacement(buffer, "X");
		}
		return buffer.toString();
	}

}

Below is Test program to above code .


package com.mask.object;
import com.model.AccountDetail;
import com.model.AddressDetail;
import com.model.CreditCardDetail;

public class MaskJavaObject {

	public static void main(String[] args) {
		AddressDetail addressDetail = new AddressDetail("Noida City Center", "Noida", "UP", "India", "20310");
		CreditCardDetail creditCardDetail = new CreditCardDetail("1234567890123456", "123", "12/90");
		AccountDetail accountDetail = new AccountDetail("Saurabh", "Gupta", addressDetail, creditCardDetail);
		System.out.println(accountDetail);
	}

}

Console Output

com.model.AccountDetail[
firstName=Saurabh
lastName=Gupta
address=com.model.AddressDetail[
addressLine1=Noida City Center
city=Noida
state=UP
pincode=India
country=20310
]
creditCardDetail=com.model.CreditCardDetail[
cardNumber=XXXXXXXXXXXXXXXX
cvv=XXX
expDate=XX/XX
]
]

Related Posts

Below are some more masking ways for different type of data like XML, JSON and printing objects before logging , sending to page or transferring over network.

Log4j2: How to Mask Logs Personal/Confidential/SPI Information

How to Mask JSON Confidential/Personal Information in logs :JAVA

How to MASK XML Confidential/Personal Data : JAVA