/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.dlect.encryption;
import com.google.common.base.Optional;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.dlect.model.Database;
/**
*
* @author lee
*/
public class DatabaseKeyHandler {
private final Key aesKey;
private DatabaseKeyHandler(Key aesKey) {
this.aesKey = aesKey;
}
public Cipher getDecryptingCipher() throws GeneralSecurityException {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, aesKey);
return c;
}
public String getEncryptedPrefix() {
StringBuilder b = new StringBuilder("ENC::");
b.append(getKeyHash());
b.append("::");
return b.toString();
}
public Cipher getEncryptingCipher() throws GeneralSecurityException {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, aesKey);
return c;
}
public String getKeyHash() {
byte[] keyBytes = aesKey.getEncoded();
BigInteger bi = new BigInteger(1, keyBytes);
return bi.toString(16);
}
public Optional<String> verifyEncrypted(String encSettingValue) {
String prefix = getEncryptedPrefix();
if (encSettingValue.startsWith(prefix)) {
return Optional.of(encSettingValue.substring(prefix.length()));
} else {
return Optional.absent();
}
}
public static DatabaseKeyHandler getKeyHandler(Database db) {
String keyString = db.getSetting(AES_KEY_SETTING_NAME);
byte[] key = null;
if (keyString != null) {
byte[] decodedKey = BytesToString.decode(keyString);
if (decodedKey.length == 16) {
key = decodedKey;
}
}
if (key == null) {
key = newKey();
db.addSetting(AES_KEY_SETTING_NAME, BytesToString.encode(key));
}
Key aesKey = new SecretKeySpec(key, "AES");
return new DatabaseKeyHandler(aesKey);
}
public static final String AES_KEY_SETTING_NAME = "AES-Key";
private static byte[] newKey() {
byte[] bytes = new SecureRandom().generateSeed(16);
return bytes;
}
}