package dbfit.util.crypto; import java.security.Key; import javax.crypto.SecretKey; import java.security.KeyStore; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; public class JKSCryptoKeyStore implements CryptoKeyStore { public static final String KS_TYPE = "JCEKS"; public static final String KS_NAME = ".dbfit.jks"; public static final char[] KS_PASS = "DbFit Access Key".toCharArray(); public static final String KEY_ALIAS = "dbfit"; private File keyStoreLocation; public JKSCryptoKeyStore(final File keyStorePath) { if (null != keyStorePath) { this.keyStoreLocation = keyStorePath; } else { this.keyStoreLocation = getDefaultKeyStoreLocation(); } } public JKSCryptoKeyStore() { this.keyStoreLocation = getDefaultKeyStoreLocation(); } private File getKeyStoreLocation() { return keyStoreLocation; } private char[] getKeyStorePassword() { return KS_PASS; } @Override public File getKeyStoreFile() { return new File(getKeyStoreLocation(), KS_NAME); } @Override public boolean keyStoreExists() { return getKeyStoreFile().exists(); } @Override public void createKeyStore() throws Exception { if (!getKeyStoreLocation().exists()) { throw new RuntimeException("No such folder: " + getKeyStoreLocation()); } if (keyStoreExists()) { throw new CryptoKeyStoreException(this, "Cannot create KeyStore on top of existing one! [" + getKeyStoreFile() + "]"); } createKeyStoreNoCheck(); } private void setKsFilePermissions() throws Exception { File ksFile = getKeyStoreFile(); ksFile.setReadable(false, false); ksFile.setWritable(false, false); ksFile.setExecutable(false, false); ksFile.setReadable(true); } private void createKeyStoreNoCheck() throws Exception { KeyStore ks = KeyStore.getInstance(KS_TYPE); ks.load(null, getKeyStorePassword()); SecretKey mySecretKey = AESKeyGenerator.generateKey(); KeyStore.SecretKeyEntry skEntry = new KeyStore.SecretKeyEntry(mySecretKey); ks.setEntry(KEY_ALIAS, skEntry, new KeyStore.PasswordProtection( getKeyStorePassword())); FileOutputStream fos = null; try { File ksFile = getKeyStoreFile(); fos = new java.io.FileOutputStream(ksFile); ks.store(fos, getKeyStorePassword()); fos.close(); setKsFilePermissions(); } finally { if (fos != null) { fos.close(); } } } public KeyStore loadKeyStore() throws Exception { KeyStore ks = KeyStore.getInstance(KS_TYPE); FileInputStream in = null; try { in = new FileInputStream(getKeyStoreFile()); ks.load(in, getKeyStorePassword()); return ks; } finally { if (null != in) { in.close(); } } } @Override public Key getKey() { try { return loadKeyStore().getKey(KEY_ALIAS, getKeyStorePassword()); } catch(Exception e) { throw new RuntimeException(e); } } private static File getDefaultKeyStoreLocation() { String ksLocation = System.getProperty("dbfit.keystore.path"); if (ksLocation == null) { ksLocation = System.getProperty("user.home"); } return new File(ksLocation); } }