Java hide password in log

Spring Boot How to Hide Passwords in Properties File

Spring Boot how to hide passwords in properties file

You can use Jasypt to encrypt properties, so you could have your property like this:

db.password=ENC(XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=)

Jasypt allows you to encrypt your properties using different algorithms, once you get the encrypted property you put inside the ENC(. ) . For instance, you can encrypt this way through Jasypt using the terminal:

encrypted-pwd$ java -cp ~/.m2/repository/org/jasypt/jasypt/1.9.2/jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="contactspassword" password=supersecretz algorithm=PBEWithMD5AndDES

----ENVIRONMENT-----------------

Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 24.45-b08

----ARGUMENTS-------------------

algorithm: PBEWithMD5AndDES
input: contactspassword
password: supersecretz

----OUTPUT----------------------

XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=

To easily configure it with Spring Boot you can use its starter jasypt-spring-boot-starter with group ID com.github.ulisesbocchio

Keep in mind, that you will need to start your application using the same password you used to encrypt the properties. So, you can start your app this way:

mvn -Djasypt.encryptor.password=supersecretz spring-boot:run

Or using the environment variable (thanks to spring boot relaxed binding):

export JASYPT_ENCRYPTOR_PASSWORD=supersecretz
mvn spring-boot:run

You can check below link for more details:

To use your encrypted properties in your app just use it as usual, use either method you like (Spring Boot wires the magic, anyway the property must be of course in the classpath):

@Value("$")
private String password;
@Autowired
private Environment environment;

public void doSomething(Environment env) System.out.println(env.getProperty("db.password"));
>

Update: for production environment, to avoid exposing the password in the command line, since you can query the processes with ps , previous commands with history , etc etc. You could:

  • Create a script like this: touch setEnv.sh
  • Edit setEnv.sh to export the JASYPT_ENCRYPTOR_PASSWORD variable

Securing a password in a properties file

Sample Image

Jasypt provides the org.jasypt.properties.EncryptableProperties class for loading, managing and transparently decrypting encrypted values in .properties files, allowing the mix of both encrypted and not-encrypted values in the same file.

By using an org.jasypt.properties.EncryptableProperties object, an
application would be able to correctly read and use a .properties file
like this:

datasource.driver=com.mysql.jdbc.Driver 
datasource.url=jdbc:mysql://localhost/reportsdb
datasource.username=reportsUser
datasource.password=ENC(G6N718UuyPE5bHyWKyuLQSm02auQPUtm)

Note that
the database password is encrypted (in fact, any other property could
also be encrypted, be it related with database configuration or not).

How do we read this value? like this:

/*
* First, create (or ask some other component for) the adequate encryptor for
* decrypting the values in our .properties file.
*/
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword("jasypt"); // could be got from web, env variable.
/*
* Create our EncryptableProperties object and load it the usual way.
*/
Properties props = new EncryptableProperties(encryptor);
props.load(new FileInputStream("/path/to/my/configuration.properties"));

/*
* To get a non-encrypted value, we just get it with getProperty.
*/
String datasourceUsername = props.getProperty("datasource.username");

/*
* . and to get an encrypted value, we do exactly the same. Decryption will
* be transparently performed behind the scenes.
*/
String datasourcePassword = props.getProperty("datasource.password");

// From now on, datasourcePassword equals "reports_passwd".

How to hide the password in the command java -Djasypt.encryptor.password=somepassword -jar name.jar

The solution what I followed was to create an environment variable with the name JASYPT_ENCRYPTOR_PASSWORD, execute the command java -jar name.jar and then unset the environment variable. This worked as I intended.

Setting an environment variable, for a short time or not doesn’t matter, isn’t a good idea. Even the shortest of time can be enough that an attacker can get access to it. There are similar attacks where the name of a temporary file could be predicted and allowed an attacker to create a link with that name to e.g. access the /etc/passwd-file, etc.

The problem exists for a while so there are a couple of solutions out there already, most of which work with a file that contains the password or a key store that is used to do encryption and decryption of sensible data.

If you look e.g. at JBoss they use something called a vault. There is a manual page explaining the single steps. You can recreate all of this for your application or just read the plain text password from a file where you specify the filename e.g. as system property. The file itself must be secured against unauthorized access on the file system level (set the read permission for the owner only) and — if necessary — within your application by setting a SecurityManager that denies access to this file by other classes than the one that is used to read it in. This is common practice with security relevant applications like PGP or OpenSSL.

Источник

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

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 ->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) < fields.length; i++) < fields[i].setAccessible(true); value = fields[i].get(object); if (value != null && fieldSet.add(fields[i].getName())) < if (fields[i].getType().isArray() || fields[i].getType().getCanonicalName().startsWith("com.mask.json")) < mask(value); >else < if (fieldNames.contains(fields[i].getName()) && 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("\\d"); Matcher matcher = pattern.matcher(text); while (matcher.find()) < matcher.appendReplacement(buffer, "X"); >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»
>
>

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.

Источник

Как спрятать символы пароля во время ввода с консоли?

Java-университет

Такой вот вопрос. Консольное приложение, пользователь вводит логин и пароль. Но во время ввода пароля необходимо «маскировать» каждый символ пароля звездочкой например, или как в линуксе просто не выводить никаких символов во время ввода пароля. Нашел вариант с использованием отдельного потока для этого. Выглядит примерно так: package main; import java.io.*; public class Main < public static void main(String[] args) < BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Enter username: "); String user = in.readLine(); Thread hide = new PasswordsHider("Enter password: "); hide.start(); String pass = in.readLine(); hide.interrupt(); >private static class PasswordsHider extends Thread < public PasswordsHider(String prompt) < super("Hiding passwords thread"); System.out.print(prompt); >@Override public void run() < while (!isInterrupted()) < System.out.print("\010"); try < Thread.sleep(1); >catch (InterruptedException e) < //e.printStackTrace(); >> > > > но во время выполнения вместо того, чтобы «затирать» вводимые символы — просто выводится на экран куча пробелов 🙂 Пробовал вместо «\010» использовать «\010*», но тогда к каждому пробелу еще звездочка добавляется)) При «\b» в выводе снова куча пробелов. Может если из командной строки запускать то будет работать, но в идее — вот так вот как я написал. Встречал, что это низкоприоритетный баг такой в Эклипс, но про идею — ни слова.

Источник

Читайте также:  Kotlin regex find all
Оцените статью