使用附加的初始化向量 java 使用流加密和解密文件
Encrypt and decrypt a file with streams, using an appended initalisation vector java
我编写了一个 Java 程序,它要求用户指定一个随机密钥(以 base 64 编码),指定要加密的明文文件,以及输出文件的名称(加密的文本文件。)
然后逆向解密(秘钥+输入加密文件+输出解密文件名)
这与 OpenSSL 提供的行为非常相似。
我的 java 代码使用模式 AES/CBC/PKCS5PADDING
.
我预先使用文件输出流将随机生成的初始化向量(16 字节 IV)附加到我的密文中。然后我相信密码输出流在IV之后写入密文。
我可以确认从加密和解密方法生成和获取的 IV 是相同的(都可以用 base64 编码打印出来,并且会匹配)。
但是,问题在于尝试解密加密文本。解密后的文本能够显示加密文本的后半部分(与原始明文的后半部分匹配)。
示例:
纯文本:my secret motto: i am awesome!
密文:<lots of encrypted characters>
解密文本:<a few encrypted characters> i am awesome!
虽然前半部分似乎被覆盖了,或者可能收集了一些奇怪的剩余加密文本。这让我相信我 encrypting/decrypting IV 使用流的方式有些不对劲。
相关执行的代码是布尔值fileStoreIV
为真时。 else 代码用于用户同时提供密钥和 IV 作为输入的情况。
因此fout.write(initVector);
和encryptedData.read(fileIV);
是代码的主要部分。
加密方式:
private static void encrypt(byte[] key, byte[] initVector, String inputFile, String outputFile) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IOException {
//Initalisation for encryption
Cipher cipher = Cipher.getInstance(CIPHER);
if(fileStoreIV) {
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
}
else {
IvParameterSpec iv = new IvParameterSpec(initVector);
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
}
//File error checking
File loadFile = new File(inputFile);
Path saveFile = Paths.get(outputFile);
Path loadFilePath = Paths.get(inputFile);
if (!Files.exists(loadFilePath)){
System.out.println("The inputFile you specified does not exist");
return;
}
Path parentDir = saveFile.getParent();
if (parentDir != null && !Files.exists(parentDir)) {
System.out.println("The outputFile directory/s you specified does not exist");
return;
}
System.out.println("Secret key is " + Base64.getEncoder().encodeToString(key));
System.out.println("IV is " + Base64.getEncoder().encodeToString(initVector));
//Special file reading and writing with 'Cipher Stream'
try (InputStream fin = FileEncryptor.class.getResourceAsStream(loadFile.getName());
OutputStream fout = Files.newOutputStream(saveFile);
CipherOutputStream cipherOut = new CipherOutputStream(fout, cipher) {
}) {
final byte[] bytes = new byte[1024];
for(int length=fin.read(bytes); length!=-1; length = fin.read(bytes)){
if(fileStoreIV) {
fout.write(initVector);
fileStoreIV = false;
}
cipherOut.write(bytes, 0, length);
}
} catch (IOException e) {
System.out.println("Something went wrong with reading and writing these files!");
System.out.println("Please check you have the latest version of this program");
System.out.println("Contact your IT admin to make sure you have sufficient privileges");
}
System.out.println("SUCCESS! Encryption finished, saved at specified location");
解密方法:
private static void decrypt(String inputKEY, String inputIV, String inputFile, String outputFile) throws NoSuchAlgorithmException, NoSuchPaddingException, IOException, InvalidKeyException, InvalidAlgorithmParameterException {
//Initalisation for decryption
Cipher cipher = Cipher.getInstance(CIPHER);
if(!fileStoreIV) {
IvParameterSpec iv = new IvParameterSpec(Base64.getDecoder().decode(inputIV));
SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(inputKEY), ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
}
Path saveFile = Paths.get(outputFile);
Path loadFilePath = Paths.get(inputFile);
if (!Files.exists(loadFilePath)){
System.out.println("The inputFile you specified does not exist");
return;
}
Path parentDir = saveFile.getParent();
if (parentDir != null && !Files.exists(parentDir)) {
System.out.println("The outputFile directory/s you specified does not exist");
return;
}
InputStream encryptedData = Files.newInputStream(loadFilePath);
if(fileStoreIV) {
{
byte[] fileIV = new byte[16];
encryptedData.read(fileIV);
System.out.println(Base64.getEncoder().encodeToString(fileIV));
SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(inputKEY), ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(fileIV));
fileStoreIV = false;
}
}
try (CipherInputStream decryptStream = new CipherInputStream(encryptedData, cipher);
OutputStream decryptedOut = Files.newOutputStream(saveFile)){
final byte[] bytes = new byte[1024];
for(int length=decryptStream.read(bytes); length!=-1; length = decryptStream.read(bytes)){
decryptedOut.write(bytes, 0, length);
}
} catch (IOException e) {
System.out.println("Something went wrong with reading and writing these files!");
System.out.println("Please check you have the latest version of this program");
System.out.println("Contact your IT admin to make sure you have sufficient privileges");
}
System.out.println("SUCESS! Decryption finished, saved at specified location");
附加说明:当我在纯文本文件之前和内部添加足够的空格时。我设法移动了足够多的文本,以显示解密文件:<a few encrypted characters> my secret motto: i am awesome!
.
解密未成功 运行 的主要部分是 Encrypt-method 中的这部分代码:
if(fileStoreIV) {
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
} else {
IvParameterSpec iv = new IvParameterSpec(initVector);
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
}
当 fileStoreIV == true
没有为 cipher.init
函数指定 IV 时。并且由于 IV 错误,解密明文的第一个块(AES 为 16 个字节)被有效地随机垃圾替换;这可能是明文的一半、全部或一小部分,具体取决于其长度(根据 @dave_thompson_085 的评论)。
我修改了你的代码,因为它由于一些其他错误而没有 运行 开箱即用,但我懒得更正它们,而是你找到了完整的 运行ning 示例代码下面。
这是程序的输出,我的 plaintext-file 包含文本 The quick brown fox jumps over the lazy dog
:
Secret key is S2guVMqVk8goYy3QsgBSMmjLLCyvoknprTGoFsxMZEo=
IV is VFIYWeCT6ixg/lwk9bBQ9g==
SUCCESS! Encryption finished, saved at specified location
SUCESS! Decryption finished, saved at specified location
Content of file decryptedtext.txt
The quick brown fox jumps over the lazy dog
代码:
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
public class FileEncryptorSo {
static String ALGORITHM = "AES";
static String CIPHER = "AES/CBC/PKCS5PADDING";
static boolean fileStoreIV = true;
public static void main(String[] args) throws IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException {
System.out.println("");
String plaintextFilename = "plaintext.txt";
String ciphertextFilename = "ciphertext.enc";
String decryptedFilename = "decryptedtext.txt";
// random aes 256 key
byte[] key = new byte[32];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(key);
// random iv
byte[] iv = new byte[16];
secureRandom.nextBytes(iv);
encrypt(key, iv, plaintextFilename, ciphertextFilename);
decrypt(Base64.getEncoder().encodeToString(key), Base64.getEncoder().encodeToString(iv), ciphertextFilename, decryptedFilename);
printTextfile(decryptedFilename);
}
private static void encrypt(byte[] key, byte[] initVector, String inputFile, String outputFile)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
//Initalisation for encryption
Cipher cipher = Cipher.getInstance(CIPHER);
IvParameterSpec iv = new IvParameterSpec(initVector);
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
/* ### leave out this part !
if (fileStoreIV) {
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
} else {
IvParameterSpec iv = new IvParameterSpec(initVector);
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
}
*/
//File error checking
// ### not used File loadFile = new File(inputFile);
Path saveFile = Paths.get(outputFile);
Path loadFilePath = Paths.get(inputFile);
if (!Files.exists(loadFilePath)) {
System.out.println("The inputFile you specified does not exist");
return;
}
Path parentDir = saveFile.getParent();
if (parentDir != null && !Files.exists(parentDir)) {
System.out.println("The outputFile directory/s you specified does not exist");
return;
}
System.out.println("Secret key is " + Base64.getEncoder().encodeToString(key));
System.out.println("IV is " + Base64.getEncoder().encodeToString(initVector));
try (FileInputStream in = new FileInputStream(inputFile);
FileOutputStream out = new FileOutputStream(outputFile);
CipherOutputStream encryptedOutputStream = new CipherOutputStream(out, cipher);) {
if (fileStoreIV) {
out.write(initVector);
// ### leave out this line fileStoreIV = false;
}
byte[] buffer = new byte[1024];
int nread;
while ((nread = in.read(buffer)) > 0) {
encryptedOutputStream.write(buffer, 0, nread);
}
encryptedOutputStream.flush();
} catch (IOException e) {
System.out.println("Something went wrong with reading and writing these files!");
System.out.println("Please check you have the latest version of this program");
System.out.println("Contact your IT admin to make sure you have sufficient privileges");
}
System.out.println("SUCCESS! Encryption finished, saved at specified location");
}
private static void decrypt(String inputKEY, String inputIV, String inputFile, String outputFile)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
//Initalisation for decryption
Cipher cipher = Cipher.getInstance(CIPHER);
if (!fileStoreIV) {
IvParameterSpec iv = new IvParameterSpec(Base64.getDecoder().decode(inputIV));
SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(inputKEY), ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
}
Path saveFile = Paths.get(outputFile);
Path loadFilePath = Paths.get(inputFile);
if (!Files.exists(loadFilePath)) {
System.out.println("The inputFile you specified does not exist");
return;
}
Path parentDir = saveFile.getParent();
if (parentDir != null && !Files.exists(parentDir)) {
System.out.println("The outputFile directory/s you specified does not exist");
return;
}
//byte[] fileIV = new byte[16];
try (FileInputStream in = new FileInputStream(inputFile);
CipherInputStream cipherInputStream = new CipherInputStream(in, cipher);
FileOutputStream out = new FileOutputStream(outputFile))
{
byte[] buffer = new byte[1024];
if (fileStoreIV) {
byte[] fileIV = new byte[16];
in.read(fileIV);
SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(inputKEY), ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(fileIV));
// ### leave out his line fileStoreIV = false;
}
int nread;
while ((nread = cipherInputStream.read(buffer)) > 0) {
out.write(buffer, 0, nread);
}
out.flush();
} catch (IOException e) {
System.out.println("Something went wrong with reading and writing these files!");
System.out.println("Please check you have the latest version of this program");
System.out.println("Contact your IT admin to make sure you have sufficient privileges");
}
System.out.println("SUCESS! Decryption finished, saved at specified location");
}
private static void printTextfile (String filename) throws IOException {
File file = new File(filename);
FileInputStream fis = new FileInputStream(file);
byte[] data = new byte[(int) file.length()];
fis.read(data);
fis.close();
String str = new String(data, "UTF-8");
System.out.println("Content of file " + filename + "\n" + str);
}
}
我编写了一个 Java 程序,它要求用户指定一个随机密钥(以 base 64 编码),指定要加密的明文文件,以及输出文件的名称(加密的文本文件。)
然后逆向解密(秘钥+输入加密文件+输出解密文件名)
这与 OpenSSL 提供的行为非常相似。
我的 java 代码使用模式 AES/CBC/PKCS5PADDING
.
我预先使用文件输出流将随机生成的初始化向量(16 字节 IV)附加到我的密文中。然后我相信密码输出流在IV之后写入密文。
我可以确认从加密和解密方法生成和获取的 IV 是相同的(都可以用 base64 编码打印出来,并且会匹配)。
但是,问题在于尝试解密加密文本。解密后的文本能够显示加密文本的后半部分(与原始明文的后半部分匹配)。
示例:
纯文本:my secret motto: i am awesome!
密文:<lots of encrypted characters>
解密文本:<a few encrypted characters> i am awesome!
虽然前半部分似乎被覆盖了,或者可能收集了一些奇怪的剩余加密文本。这让我相信我 encrypting/decrypting IV 使用流的方式有些不对劲。
相关执行的代码是布尔值fileStoreIV
为真时。 else 代码用于用户同时提供密钥和 IV 作为输入的情况。
因此fout.write(initVector);
和encryptedData.read(fileIV);
是代码的主要部分。
加密方式:
private static void encrypt(byte[] key, byte[] initVector, String inputFile, String outputFile) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IOException {
//Initalisation for encryption
Cipher cipher = Cipher.getInstance(CIPHER);
if(fileStoreIV) {
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
}
else {
IvParameterSpec iv = new IvParameterSpec(initVector);
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
}
//File error checking
File loadFile = new File(inputFile);
Path saveFile = Paths.get(outputFile);
Path loadFilePath = Paths.get(inputFile);
if (!Files.exists(loadFilePath)){
System.out.println("The inputFile you specified does not exist");
return;
}
Path parentDir = saveFile.getParent();
if (parentDir != null && !Files.exists(parentDir)) {
System.out.println("The outputFile directory/s you specified does not exist");
return;
}
System.out.println("Secret key is " + Base64.getEncoder().encodeToString(key));
System.out.println("IV is " + Base64.getEncoder().encodeToString(initVector));
//Special file reading and writing with 'Cipher Stream'
try (InputStream fin = FileEncryptor.class.getResourceAsStream(loadFile.getName());
OutputStream fout = Files.newOutputStream(saveFile);
CipherOutputStream cipherOut = new CipherOutputStream(fout, cipher) {
}) {
final byte[] bytes = new byte[1024];
for(int length=fin.read(bytes); length!=-1; length = fin.read(bytes)){
if(fileStoreIV) {
fout.write(initVector);
fileStoreIV = false;
}
cipherOut.write(bytes, 0, length);
}
} catch (IOException e) {
System.out.println("Something went wrong with reading and writing these files!");
System.out.println("Please check you have the latest version of this program");
System.out.println("Contact your IT admin to make sure you have sufficient privileges");
}
System.out.println("SUCCESS! Encryption finished, saved at specified location");
解密方法:
private static void decrypt(String inputKEY, String inputIV, String inputFile, String outputFile) throws NoSuchAlgorithmException, NoSuchPaddingException, IOException, InvalidKeyException, InvalidAlgorithmParameterException {
//Initalisation for decryption
Cipher cipher = Cipher.getInstance(CIPHER);
if(!fileStoreIV) {
IvParameterSpec iv = new IvParameterSpec(Base64.getDecoder().decode(inputIV));
SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(inputKEY), ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
}
Path saveFile = Paths.get(outputFile);
Path loadFilePath = Paths.get(inputFile);
if (!Files.exists(loadFilePath)){
System.out.println("The inputFile you specified does not exist");
return;
}
Path parentDir = saveFile.getParent();
if (parentDir != null && !Files.exists(parentDir)) {
System.out.println("The outputFile directory/s you specified does not exist");
return;
}
InputStream encryptedData = Files.newInputStream(loadFilePath);
if(fileStoreIV) {
{
byte[] fileIV = new byte[16];
encryptedData.read(fileIV);
System.out.println(Base64.getEncoder().encodeToString(fileIV));
SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(inputKEY), ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(fileIV));
fileStoreIV = false;
}
}
try (CipherInputStream decryptStream = new CipherInputStream(encryptedData, cipher);
OutputStream decryptedOut = Files.newOutputStream(saveFile)){
final byte[] bytes = new byte[1024];
for(int length=decryptStream.read(bytes); length!=-1; length = decryptStream.read(bytes)){
decryptedOut.write(bytes, 0, length);
}
} catch (IOException e) {
System.out.println("Something went wrong with reading and writing these files!");
System.out.println("Please check you have the latest version of this program");
System.out.println("Contact your IT admin to make sure you have sufficient privileges");
}
System.out.println("SUCESS! Decryption finished, saved at specified location");
附加说明:当我在纯文本文件之前和内部添加足够的空格时。我设法移动了足够多的文本,以显示解密文件:<a few encrypted characters> my secret motto: i am awesome!
.
解密未成功 运行 的主要部分是 Encrypt-method 中的这部分代码:
if(fileStoreIV) {
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
} else {
IvParameterSpec iv = new IvParameterSpec(initVector);
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
}
当 fileStoreIV == true
没有为 cipher.init
函数指定 IV 时。并且由于 IV 错误,解密明文的第一个块(AES 为 16 个字节)被有效地随机垃圾替换;这可能是明文的一半、全部或一小部分,具体取决于其长度(根据 @dave_thompson_085 的评论)。
我修改了你的代码,因为它由于一些其他错误而没有 运行 开箱即用,但我懒得更正它们,而是你找到了完整的 运行ning 示例代码下面。
这是程序的输出,我的 plaintext-file 包含文本 The quick brown fox jumps over the lazy dog
:
Secret key is S2guVMqVk8goYy3QsgBSMmjLLCyvoknprTGoFsxMZEo=
IV is VFIYWeCT6ixg/lwk9bBQ9g==
SUCCESS! Encryption finished, saved at specified location
SUCESS! Decryption finished, saved at specified location
Content of file decryptedtext.txt
The quick brown fox jumps over the lazy dog
代码:
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
public class FileEncryptorSo {
static String ALGORITHM = "AES";
static String CIPHER = "AES/CBC/PKCS5PADDING";
static boolean fileStoreIV = true;
public static void main(String[] args) throws IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException {
System.out.println("");
String plaintextFilename = "plaintext.txt";
String ciphertextFilename = "ciphertext.enc";
String decryptedFilename = "decryptedtext.txt";
// random aes 256 key
byte[] key = new byte[32];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(key);
// random iv
byte[] iv = new byte[16];
secureRandom.nextBytes(iv);
encrypt(key, iv, plaintextFilename, ciphertextFilename);
decrypt(Base64.getEncoder().encodeToString(key), Base64.getEncoder().encodeToString(iv), ciphertextFilename, decryptedFilename);
printTextfile(decryptedFilename);
}
private static void encrypt(byte[] key, byte[] initVector, String inputFile, String outputFile)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
//Initalisation for encryption
Cipher cipher = Cipher.getInstance(CIPHER);
IvParameterSpec iv = new IvParameterSpec(initVector);
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
/* ### leave out this part !
if (fileStoreIV) {
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
} else {
IvParameterSpec iv = new IvParameterSpec(initVector);
SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
}
*/
//File error checking
// ### not used File loadFile = new File(inputFile);
Path saveFile = Paths.get(outputFile);
Path loadFilePath = Paths.get(inputFile);
if (!Files.exists(loadFilePath)) {
System.out.println("The inputFile you specified does not exist");
return;
}
Path parentDir = saveFile.getParent();
if (parentDir != null && !Files.exists(parentDir)) {
System.out.println("The outputFile directory/s you specified does not exist");
return;
}
System.out.println("Secret key is " + Base64.getEncoder().encodeToString(key));
System.out.println("IV is " + Base64.getEncoder().encodeToString(initVector));
try (FileInputStream in = new FileInputStream(inputFile);
FileOutputStream out = new FileOutputStream(outputFile);
CipherOutputStream encryptedOutputStream = new CipherOutputStream(out, cipher);) {
if (fileStoreIV) {
out.write(initVector);
// ### leave out this line fileStoreIV = false;
}
byte[] buffer = new byte[1024];
int nread;
while ((nread = in.read(buffer)) > 0) {
encryptedOutputStream.write(buffer, 0, nread);
}
encryptedOutputStream.flush();
} catch (IOException e) {
System.out.println("Something went wrong with reading and writing these files!");
System.out.println("Please check you have the latest version of this program");
System.out.println("Contact your IT admin to make sure you have sufficient privileges");
}
System.out.println("SUCCESS! Encryption finished, saved at specified location");
}
private static void decrypt(String inputKEY, String inputIV, String inputFile, String outputFile)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
//Initalisation for decryption
Cipher cipher = Cipher.getInstance(CIPHER);
if (!fileStoreIV) {
IvParameterSpec iv = new IvParameterSpec(Base64.getDecoder().decode(inputIV));
SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(inputKEY), ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
}
Path saveFile = Paths.get(outputFile);
Path loadFilePath = Paths.get(inputFile);
if (!Files.exists(loadFilePath)) {
System.out.println("The inputFile you specified does not exist");
return;
}
Path parentDir = saveFile.getParent();
if (parentDir != null && !Files.exists(parentDir)) {
System.out.println("The outputFile directory/s you specified does not exist");
return;
}
//byte[] fileIV = new byte[16];
try (FileInputStream in = new FileInputStream(inputFile);
CipherInputStream cipherInputStream = new CipherInputStream(in, cipher);
FileOutputStream out = new FileOutputStream(outputFile))
{
byte[] buffer = new byte[1024];
if (fileStoreIV) {
byte[] fileIV = new byte[16];
in.read(fileIV);
SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(inputKEY), ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(fileIV));
// ### leave out his line fileStoreIV = false;
}
int nread;
while ((nread = cipherInputStream.read(buffer)) > 0) {
out.write(buffer, 0, nread);
}
out.flush();
} catch (IOException e) {
System.out.println("Something went wrong with reading and writing these files!");
System.out.println("Please check you have the latest version of this program");
System.out.println("Contact your IT admin to make sure you have sufficient privileges");
}
System.out.println("SUCESS! Decryption finished, saved at specified location");
}
private static void printTextfile (String filename) throws IOException {
File file = new File(filename);
FileInputStream fis = new FileInputStream(file);
byte[] data = new byte[(int) file.length()];
fis.read(data);
fis.close();
String str = new String(data, "UTF-8");
System.out.println("Content of file " + filename + "\n" + str);
}
}