Cryptography
SeedStack support easy configuration of Java key stores and SSL along with services for private key encryption and secure hashing.
Trust store
The trust store is a storage facility for certificate authority (CA) certificates. They often contain the full certification chain up to the top-level CA. It is configured as below:
crypto:
# Configured trust store
truststore:
# Path of the key store
path: (String)
# Password of the key store
password: (String)
# [Optional] Type of the key store (use the default key store type if not specified)
type: (String)
# [Optional] The security provider to use (will default to the registered list if not provided)
provider: (String)
To dump the crypto.truststore
configuration options:
mvn -q -Dargs="crypto.truststore" seedstack:config
The trust store is notably used by the TLS stack to validate certificates presented by clients doing mutual authentication.
Key stores
A key store is a storage facility for cryptographic keys and certificates. Key stores are created using the keytool
command-line tool (see keytool documentation).
Here is an example creating a key store named some.keystore
with a key pair named alias1
:
keytool -genkeypair -dname "cn=Mark Jones, ou=Java, o=Oracle, c=US" -keystore some.keystore -storepass <keystore password> -validity 180 -alias alias1 -keypass <alias password>
You can configure key stores in your application as below:
crypto:
# Configured key stores
keystores:
# Logical name of the key store
keystore1:
# Path of the key store
path: (String)
# Password of the key store
password: (String)
# [Optional] Type of the key store (use the default key store type if not specified)
type: (String)
# [Optional] The security provider to use (will default to the registered list if not provided)
provider: (String)
# Configured aliases in the key store
aliases:
# Name of the alias in the key store
alias1:
# Password of the alias
password: (String)
# String qualifier to use for injecting the cryptography services (defaults to the name of the alias if not specified)
qualifier: (String)
To dump the crypto.keystores
configuration options:
mvn -q -Dargs="crypto.keystores" seedstack:config
Encryption and decryption
You can use a key/pair from a key store or a certificate to encrypt and decrypt data. Just inject an
EncryptionService
qualified with the alias or certificate name:
public class SomeClass {
@Inject
@Named("alias1")
private EncryptionService encryptionService1;
@Inject
@Named("certificate1")
private EncryptionService encryptionService2;
}
- The service
encryptionService1
will encrypt and decrypt data using the key/pair namedalias1
stored inkeystore1
. - The service
encryptionService2
will encrypt and decrypt data using the key/pair from the certificatecertificate1
.
By default, the name of the alias is used as the injection qualifier. When multiple key stores contain the same alias
name, you can specify a different qualifier in the qualifier
configuration option of the concerned alias(es).
You can encrypt and decrypt data with as below:
public class SomeClass {
@Inject
@Named("alias1")
private EncryptionService encryptionService;
public byte[] encrypt(byte[] data) {
return encryptionService.encrypt(data);
}
public byte[] decrypt(byte[] data) {
return encryptionService.decrypt(data);
}
}
Secure hashing
You can do secure hashing using the PBKDF2WithHmacSHA1
algorithm by injecting the HashingService
interface:
public class SomeClass {
@Inject
private HashingService hashingService;
public void hash(char[] password) {
// Hashes the password returning an object containing the salt value and the hash value
Hash hash = hashingService.createHash(password);
}
public void validate(char[] password, Hash knownHash) {
// Validate the password against an already known hash
boolean valid = hashingService.validatePassword(password, knownHash);
}
}
Encrypting configuration values
The decrypt function
Sometimes you are required to put sensitive data, like passwords, in configuration files. You can choose to encrypt
such sensitive data and let SeedStack decrypt it only at runtime when needed. This is done with the $decrypt(alias, value)
configuration function:
crypto:
keystores:
master:
path: master.keystore
password: ${env.MASTER_KS_PASSWORD}
aliases:
alias1:
password: ${env.MASTER_KS_ALIAS1_PASSWORD}
myConfig:
password: $decrypt('alias1', '5BC99359A5...A49580F0DE3')
The myConfig.password
value is encrypted in the files and only decrypted on-the-fly when accessed by the application:
* The key store named master
is always used for decrypting values.
* The alias used to decrypt values is specified as the first argument of the $decrypt
function.
The master key store and its aliases passwords must be left unencrypted. To avoid a security hole, you need to externalize those passwords and provide them only at runtime, in a secured manner. All others sensitive values can be encrypted.
The crypt tool
To crypt configuration values, you can use the crypt
tool provided by SeedStack. You can call it with the
crypt goal of the SeedStack Maven plugin:
mvn -Dargs="--alias alias1 thePasswOrd" -q org.seedstack:seedstack-maven-plugin:crypt
This will crypt the value thePasswOrd
with the key in the alias1
alias of the configure master
key store.
You must have a master
key store already configured in your application.
SSL
The SSL configuration required for HTTPS operation of embedded Web servers such as the built-in Undertow can be found below:
crypto:
ssl:
# The password used to retrieve a matching SSL certificate from the keystore
keyPassword: (String)
# Name of the configured keystore used for SSL ('master' by default)
keyStore: (String)
# The client authentication mode (used for mutual certificate authentication)
clientAuthMode: (NOT_REQUESTED|REQUESTED|REQUIRED)
# A custom X509KeyManager implementation allowing to control the alias selection process
x509KeyManager: (Class<? extends X509KeyManager>)
# The protocol to use for SSL communication ('TLS' by default)
protocol: (String)
# The set of ciphers that can be used for SSL communication
ciphers: [ (String) ]
To dump the crypto.ssl
configuration options:
mvn -q -Dargs="crypto.ssl" seedstack:config
The keyPassword
option must match at least one alias password in the keystore used for SSL (master by default).
If multiple aliases have the same password, a choice is made by the SSL default implementation. You can control this choice by specifying an implementation of X509KeyManager
in the x509KeyManager
configuration option.