Skip to content

Instantly share code, notes, and snippets.

@h1ddengames
Last active May 20, 2020 19:36
Show Gist options
  • Save h1ddengames/ddb14a4387a4fd2d7512a608d6f1bf50 to your computer and use it in GitHub Desktop.
Save h1ddengames/ddb14a4387a4fd2d7512a608d6f1bf50 to your computer and use it in GitHub Desktop.
Storing login and other data securely in a properties file

Storing login and other data in a properties file

Unencrypted storing of properties

  1. Create a properties file template that stores all the data keys your application will use -- you can leave it blank after the equal sign or fill in garbage data.
  2. Create another properties file that contains the same data keys as the template but the actual values your application will use.
  3. Make sure to add the app.properties file to gitignore to prevent adding the file to your repository.

Encrypted storing of properties

  1. Create a properties file template that stores all the data keys your application will use -- you can leave it blank after the equal sign or fill in garbage data.
  2. Create another properties file that contains the same data keys as the template but the actual values your application will use.
  3. Make sure to add the app.properties file to gitignore to prevent adding the file to your repository.
  4. Using MuleSoft Secure Configuration Properties (found here: https://docs.mulesoft.com/mule-runtime/4.1/secure-configuration-properties) encrypt your property values. See EncryptThenDecryptTest.java attached below for an example on usage.
# THIS IS A TEMPLATE FILE -- PLEASE CREATE A LOCAL COPY WITH THE FOLLOWING CONTENTS AND REMOVE -TEMPLATE from the name.
app.version=1.0
app.name=TestApp
app.date=05-19-20
app.encryption.key=PleaseRememberAndChangeThis-SinceItWillBeChangedOrDeletedAfterEncryption
some.domain.login.username=pleasechangethis1
some.domain.login.password=pleasechangethis2
another.domain.login.username=pleasechangethis3
another.domain.login.password=pleasechangethis4
database.login.username=pleasechangethis5
database.login.password=pleasechangethis6
app.version=1.0
app.name=TestApp
app.date=05-19-20
app.encryption.key=supersecurepassword
some.domain.login.username=pleasechangethis1
some.domain.login.password=pleasechangethis2
another.domain.login.username=pleasechangethis3
another.domain.login.password=pleasechangethis4
database.login.username=pleasechangethis5
database.login.password=pleasechangethis6
app.version=![RTYz4sFLo5c=]
app.name=![QnXkRXnTYQw=]
app.date=![lJKMq6HSpj5vFqwCvUx71w==]
some.domain.login.username=![gdCDmDPVCd1sLbad30Jawh5sFFvOzFs/]
some.domain.login.password=![gdCDmDPVCd1sLbad30JawqjmITMqeMV4]
another.domain.login.username=![gdCDmDPVCd1sLbad30JawpTipcw+dJvJ]
another.domain.login.password=![gdCDmDPVCd1sLbad30JawnreyhOJ9mcM]
database.login.username=![gdCDmDPVCd1sLbad30Jawj4yRsgfjiSD]
database.login.password=![gdCDmDPVCd1sLbad30Jawp3bPZiibN7A]
package xyz.hiddengames;
import com.mulesoft.tools.SecurePropertiesTool;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.FileBasedConfiguration;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.fluent.Parameters;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
// App flow:
// On first git clone/ project creation:
// Create app-TEMPLATE.properties and app.properties files.
// Next add all the properties your app will require to both of the above files.
// Make sure to scrub sensitive information from the app-TEMPLATE.properties file since it will be tracked by git.
// Then add app.properties , app-encrypted.properties , and app-decrypted.properties to .gitignore
// Run minimumRequiredStepsToEncrypt() to encrypt the properties values.
// When the app is running and it requires a property value, run minimumRequiredStepsToDecrypt()
// Once you've stored the required properties or before the app closes, delete the app-decrypted.properties file through code.
public class EncryptThenDecryptTest {
public Logger logger = LoggerFactory.getLogger(this.getClass());
Properties properties = new Properties();
Parameters params = new Parameters();;
Configuration config;
FileBasedConfigurationBuilder<FileBasedConfiguration> builder;
// Keep app-TEMPLATE.properties in the list of tracked files for your project.
// Add app.properties , app-encrypted.properties , app-decrypted.properties to .gitignore
@Test
public void minimumRequiredStepsToEncrypt() {
// Use normal properties to find the encryption key.
loadPropertiesFromFile("src\\main\\resources\\app.properties");
// Store the encryption key.
String encryptionKey = properties.getProperty("app.encryption.key");
// Encrypt all properties and save into a new file.
encryptOrDecrypt("encrypt",
encryptionKey,
"src\\main\\resources\\app.properties",
"src\\main\\resources\\app-encrypted.properties");
// Use apache configuration to remove the encryption key from the properties file.
setupBuilder("src\\main\\resources\\app-encrypted.properties");
clearPropertyAndSave("app.encryption.key");
}
// Add app.encryption.key key with the password that was used to encrypt the properties file then run this method.
// Or ask the user to input the password that was used to encrypt the properties file.
@Test
public void minimumRequiredStepsToDecrypt() {
// Use normal properties to find the encryption key.
loadPropertiesFromFile("src\\main\\resources\\app-encrypted.properties");
// Store the decryption key.
String decryptionKey = properties.getProperty("app.encryption.key");
// Decrypt all properties and save into a new file.
encryptOrDecrypt("decrypt",
decryptionKey,
"src\\main\\resources\\app-encrypted.properties",
"src\\main\\resources\\app-decrypted.properties");
// Use apache configuration to remove the encryption key from the properties file.
setupBuilder("src\\main\\resources\\app-encrypted.properties");
clearPropertyAndSave("app.encryption.key");
//deleteDecryptedProperties();
}
@Test
public void EncryptionAndDecryptionTest() {
// Use normal properties to find the encryption key.
loadPropertiesFromFile("src\\main\\resources\\app.properties");
// Store the encryption key.
String encryptionKey = properties.getProperty("app.encryption.key");
String decryptionKey = properties.getProperty("app.encryption.key");
// Encrypt all properties and save into a new file.
encryptOrDecrypt("encrypt",
encryptionKey,
"src\\main\\resources\\app.properties",
"src\\main\\resources\\app-encrypted.properties");
// Use apache configuration to remove the encryption key from the properties file.
setupBuilder("src\\main\\resources\\app-encrypted.properties");
clearPropertyAndSave("app.encryption.key");
// Validate that the encryption key-value pair has been removed.
// Validate that the encryption was successful.
loadPropertiesFromFile("src\\main\\resources\\app-encrypted.properties");
Assert.assertEquals(properties.getOrDefault("app.encryption.key", "ERROR_NOTFOUND"), "ERROR_NOTFOUND");
Assert.assertNotEquals(properties.getOrDefault("some.domain.login.username", "ERROR_NOTFOUND"), "pleasechangethis1");
Assert.assertNotEquals(properties.getOrDefault("some.domain.login.password", "ERROR_NOTFOUND"), "pleasechangethis2");
// Decrypt all properties and save into a new file.
encryptOrDecrypt("decrypt",
decryptionKey,
"src\\main\\resources\\app-encrypted.properties",
"src\\main\\resources\\app-decrypted.properties");
// Validate that the decryption was successful.
loadPropertiesFromFile("src\\main\\resources\\app-decrypted.properties");
Assert.assertEquals(properties.getOrDefault("some.domain.login.username", "ERROR_NOTFOUND"), "pleasechangethis1");
Assert.assertEquals(properties.getOrDefault("some.domain.login.password", "ERROR_NOTFOUND"), "pleasechangethis2");
}
public void deleteDecryptedProperties() {
try{
FileUtils.forceDelete(new File("src\\main\\resources\\app-decrypted.properties"));
} catch (Exception e) { e.printStackTrace(); }
}
public void loadPropertiesFromFile(String path) {
try(FileInputStream inputStream = new FileInputStream(path)) {
properties = new Properties();
properties.load(inputStream);
} catch(Exception e) { e.printStackTrace(); }
}
public void setupBuilder(String filePath) {
try {
builder = new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class)
.configure(params.properties()
.setFileName(filePath));
config = builder.getConfiguration();
} catch(ConfigurationException e) { e.printStackTrace(); }
}
public void updatePropertyAndSave(String propertyKey, String propertyValue) {
try {
config.setProperty(propertyKey, propertyValue);
builder.save();
} catch (ConfigurationException e) {
e.printStackTrace();
}
}
public void clearPropertyAndSave(String propertyKey) {
try {
config.clearProperty(propertyKey);
builder.save();
} catch (ConfigurationException e) {
e.printStackTrace();
}
}
public void encryptOrDecrypt(String operation, String key, String inputPath, String outputPath) {
SecurePropertiesTool.main(
new String[] { "file",
operation,
"Blowfish",
"CBC",
key,
inputPath,
outputPath });
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment