Использование шифрования на основе пароля для файла в Java
Я пытаюсь зашифровать содержимое одного файла в другой файл с помощью ключевой фразы в Java. Файл считывается в байтовый массив, шифруется в другой байтовый массив, а затем записывается в новый файл. К сожалению, когда я пытаюсь изменить шифрование, выходной файл расшифровывается как мусор.
Я сильно подозреваю, что проблема связана с генерацией идентичного ключа каждый раз, когда используется одна и та же фраза-пароль. Я написал метод тестирования, который выдает ключ в файл всякий раз, когда его генерируют. Ключ записывается как напрямую, так и в зашифрованном виде. Первое всегда идентично, но последнее всегда почему-то отличается.
Честно говоря, я неМного знаю о методах шифрования, особенно в Java. Мне нужны только данные, чтобы быть в меру защищенной, а шифрование неВы должны противостоять атаке любого, у кого есть значительное время и навыки. Заранее спасибо всем, у кого есть советы по этому вопросу.
Изменить: Esailija был достаточно любезен, чтобы указать, что я всегда устанавливал шифр с ENCRYPT_MODE. Я исправил проблему, используя логический аргумент, но теперь ям получаю следующее исключение:
javax.crypto.IllegalBlockSizeException: входная длина должна быть кратна 8 при дешифровании с добавленным шифром
Это звучит как парольная фразат используется правильно. У меня сложилось впечатление, что "PBEWithMD5AndDES» хеширует его в 16-байтовый код, который, безусловно, кратен 8. ЯМне интересно, почему ключ генерируется и используется просто отлично для режима шифрования, но потом жалуется, когда пытается расшифровать в тех же условиях.
import java.various.stuff;
/**Utility class to encrypt and decrypt files**/
public class FileEncryptor {
//Arbitrarily selected 8-byte salt sequence:
private static final byte[] salt = {
(byte) 0x43, (byte) 0x76, (byte) 0x95, (byte) 0xc7,
(byte) 0x5b, (byte) 0xd7, (byte) 0x45, (byte) 0x17
};
private static Cipher makeCipher(String pass, Boolean decryptMode) throws GeneralSecurityException{
//Use a KeyFactory to derive the corresponding key from the passphrase:
PBEKeySpec keySpec = new PBEKeySpec(pass.toCharArray());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(keySpec);
//Create parameters from the salt and an arbitrary number of iterations:
PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 42);
/*Dump the key to a file for testing: */
FileEncryptor.keyToFile(key);
//Set up the cipher:
Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
//Set the cipher mode to decryption or encryption:
if(decryptMode){
cipher.init(Cipher.ENCRYPT_MODE, key, pbeParamSpec);
} else {
cipher.init(Cipher.DECRYPT_MODE, key, pbeParamSpec);
}
return cipher;
}
/**Encrypts one file to a second file using a key derived from a passphrase:**/
public static void encryptFile(String fileName, String pass)
throws IOException, GeneralSecurityException{
byte[] decData;
byte[] encData;
File inFile = new File(fileName);
//Generate the cipher using pass:
Cipher cipher = FileEncryptor.makeCipher(pass, false);
//Read in the file:
FileInputStream inStream = new FileInputStream(inFile);
decData = new byte[(int)inFile.length()];
inStream.read(decData);
inStream.close();
//Encrypt the file data:
encData = cipher.doFinal(decData);
//Write the encrypted data to a new file:
FileOutputStream outStream = new FileOutputStream(new File(fileName + ".encrypted"));
outStream.write(encData);
outStream.close();
}
/**Decrypts one file to a second file using a key derived from a passphrase:**/
public static void decryptFile(String fileName, String pass)
throws GeneralSecurityException, IOException{
byte[] encData;
byte[] decData;
File inFile = new File(fileName);
//Generate the cipher using pass:
Cipher cipher = FileEncryptor.makeCipher(pass, true);
//Read in the file:
FileInputStream inStream = new FileInputStream(inFile);
encData = new byte[(int)inFile.length()];
inStream.read(encData);
inStream.close();
//Decrypt the file data:
decData = cipher.doFinal(encData);
//Write the decrypted data to a new file:
FileOutputStream target = new FileOutputStream(new File(fileName + ".decrypted.txt"));
target.write(decData);
target.close();
}
/**Record the key to a text file for testing:**/
private static void keyToFile(SecretKey key){
try {
File keyFile = new File("C:\\keyfile.txt");
FileWriter keyStream = new FileWriter(keyFile);
String encodedKey = "\n" + "Encoded version of key: " + key.getEncoded().toString();
keyStream.write(key.toString());
keyStream.write(encodedKey);
keyStream.close();
} catch (IOException e) {
System.err.println("Failure writing key to file");
e.printStackTrace();
}
}
}