Actualmente estoy trabajando en un programa de cifrado de archivos usando Java Cryptography Architecture.
Mi plan es tener una serie de archivos cifrados donde cada archivo tenga una clave AES diferente. Para realizar un seguimiento de los archivos cifrados también incluyo un archivo de metadatos que almacena una entrada para cada archivo cifrado con los siguientes valores: nombre de archivo de texto sin formato, nombre de archivo cifrado y clave AES.
El archivo de metadatos se encripta utilizando una clave AES que se deriva de la contraseña del usuario.
Mi pregunta es ¿Debo implementar un modo? y ¿cree que mantener todas las contraseñas en los metadatos cifrados es una práctica aceptable?
Aquí está el código al que me he referido:
public class PasswordBasedEncryption {
PBEKeySpec pbeKeySpec;
PBEParameterSpec pbeParamSpec;
SecretKeyFactory keyFac;
// Salt
byte[] salt = {
(byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
(byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
};
// Iteration count
int count = 65536;
int keySize = 128;
Cipher pbeCipher;
SecretKey pbeKey;
FileInputStream fis;
FileOutputStream fos;
/**
* constructor given a master password
* Use password based derivation function II to make AES key.
* used only for the metadata file encryption
* @param password
*/
public PasswordBasedEncryption(char[] password){
try{
keyFac = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
pbeKeySpec = new PBEKeySpec(password, salt, count, keySize);
SecretKey tempKey = keyFac.generateSecret(pbeKeySpec);
pbeKey = new SecretKeySpec(tempKey.getEncoded(), "AES");
pbeCipher = Cipher.getInstance("AES");
}
catch (Exception e){e.printStackTrace();}
}
/**
* constructor given a generated AES key
* each file has its own AES key to avoid known text attacks
* @param key
*/
public PasswordBasedEncryption(SecretKey key){
try{
pbeKey = key;
}
catch (Exception e){e.printStackTrace();}
}
public void encrypt(String filePath, String cipherName){
try{
File clearFile = new File(filePath);
fis = new FileInputStream(clearFile);
pbeCipher = Cipher.getInstance("AES");
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey);
CipherInputStream cis = new CipherInputStream(fis, pbeCipher);
File cipherFile = new File(Path.TEMP + cipherName);
fos = new FileOutputStream(cipherFile);
int read;
while((read = cis.read())!=-1)
{
fos.write((char)read);
fos.flush();
}
cis.close();
fos.close();
fis.close();
}
catch(Exception e ){e.printStackTrace();}
}
public void decrypt(String cipherName, String filePath){
try{
fis = new FileInputStream(Path.TEMP + cipherName);
File clearFile = new File(filePath);
fos = new FileOutputStream(clearFile);
pbeCipher = Cipher.getInstance("AES");
pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey);
CipherOutputStream cos = new CipherOutputStream(fos, pbeCipher);
int read;
while((read = fis.read())!=-1)
{
cos.write(read);
cos.flush();
}
cos.close();
fis.close();
fos.close();
}
catch(Exception e ){e.printStackTrace();}
}
/**
* Generate secret password used each time a new file needs encrypting
* @return
*/
public static SecretKey genPass(){
KeyGenerator keyGen;
try {
keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
return keyGen.generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
}