
org.slingshot.crypto.bouncycastle.BouncyCastleAESKeyStore Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of CryptoBouncyCastle Show documentation
Show all versions of CryptoBouncyCastle Show documentation
An implementation of the Crypto API that relys on BounceyCastle to perform AES symmteric key encryption.
Contains logic to help construct and lookup keys.
The newest version!
package org.slingshot.crypto.bouncycastle;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.PosixFilePermissions;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.ConcurrentHashMap;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import org.bouncycastle.util.encoders.Encoder;
import org.bouncycastle.util.encoders.HexEncoder;
import org.slingshot.crypto.CryptoException;
/**
* A means of generating, storing and retrieving AES keys.
*
* @author rex
*/
public class BouncyCastleAESKeyStore {
/**
* {@link Charset} used to represent the bytes of the hex encoded binary string.
*/
private static final Charset CHARSET = Charset.forName("UTF8");
/**
* Encodes the binary stream to hexadecimal values as the first pass before writing values to a file.
*/
private static final Encoder ENCODER = new HexEncoder();
/**
* Folder storing the key files
*/
private final Path keyDir;
/**
* AES key size
*/
private static final Integer AES_KEY_SIZE = 256;
private static final ConcurrentHashMap KNOWN_KEYS = new ConcurrentHashMap<>();
/**
* Uses the file location you specify as a root directory for all keys stored by keyName.
*
* @param keyDir
*/
public BouncyCastleAESKeyStore(final Path keyDir) {
if (keyDir != null) {
this.keyDir = keyDir;
} else {
throw new CryptoException("Key path must be non-null");
}
if (!keyDir.toFile().exists() && !keyDir.toFile().mkdirs() && !keyDir.toFile().mkdir()) {
throw new CryptoException("Could not create path: " + keyDir.toString());
}
}
private byte[] generateKey() {
KeyGenerator kg = null;
try {
kg = KeyGenerator.getInstance("AES");
kg.init(AES_KEY_SIZE);
final SecretKey sk = kg.generateKey();
return sk.getEncoded();
} catch (final NoSuchAlgorithmException nsae) {
throw new CryptoException("Could not find the AES key gen instance", nsae);
}
}
/**
* Creates a key retrievable with the inputed from this key store.
* @param name the name of the key
*/
public void createKey(final String name) {
final byte[] key = generateKey();
try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
ENCODER.encode(key, 0, key.length, stream);
final String encodedKey = new String(stream.toByteArray(), CHARSET);
final Path keyPath = keyDir.resolve(name);
if (!keyDir.toFile().exists() && !keyDir.toFile().mkdirs()) {
throw new CryptoException("Could not create key store directory : " + keyDir.getParent().toString());
}
Files.write(keyPath, encodedKey.getBytes(CHARSET), StandardOpenOption.CREATE);
ensureNotReadableByNonOwner(keyPath);
KNOWN_KEYS.putIfAbsent(name, key);
} catch (final IOException ioe) {
throw new CryptoException(ioe);
}
}
/**
* Changes the file permissions if available
*
* @param path
* @throws IOException
*/
private void ensureNotReadableByNonOwner(final Path path) throws IOException {
if (!System.getProperty("os.name").toLowerCase().contains("win")) {
Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rw-------"));
}
}
/**
* Retrieves the key from the keystore.
*
* @param name the name of the key
* @return raw byte material of key
*/
public byte[] retreiveKey(final String name) {
if (KNOWN_KEYS.contains(name)) {
return KNOWN_KEYS.get(name);
}
final Path keyFile = keyDir.resolve(name);
if (!keyFile.toFile().exists()) {
return null;
}
try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
ENCODER.decode(new String(Files.readAllBytes(keyFile), CHARSET), stream);
ensureNotReadableByNonOwner(keyFile);
KNOWN_KEYS.putIfAbsent(name, stream.toByteArray());
return KNOWN_KEYS.get(name);
} catch (final IOException ioe) {
throw new CryptoException(ioe);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy