问题
In my project a textfile is chosen and become encrypted. The encrypted text is saved seperatly as well as the key. Now I try to create a program which is decrypting the file when the right keyfile is available. I think the decrypting program needs to look pretty like the encrypting program just in DECRYPT_MODE
. When I read in the key I don't know how to do the next step at it to decrypt the textfile. Maybe anyone can help me how I use the key from .txt file and use it to decrypt the encoded file.
The encrypting program:
public class encrypt {
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException {
//Key is created and saved in File
KeyGenerator keygenerator = KeyGenerator.getInstance("AES");
SecretKey myDesKey = keygenerator.generateKey();
String encodedKey = Base64.getEncoder().encodeToString(myDesKey.getEncoded());
Path keypath = Paths.get("C:/xxx/key.txt");
Path keyfile = Files.createFile(keypath);
Files.write(keyfile, encodedKey.getBytes(), StandardOpenOption.WRITE);
Cipher desalgCipher;
desalgCipher = Cipher.getInstance("AES");
desalgCipher.init(Cipher.ENCRYPT_MODE, myDesKey);
Path target = Paths.get("C:/xxx/encrypted.txt");
Path file = Files.createFile(target);
Path path = Paths.get("test.txt");
try(InputStream is = Files.newInputStream(path);
CipherInputStream cipherIS = new CipherInputStream(is, desalgCipher);
BufferedReader reader = new BufferedReader(new InputStreamReader(cipherIS));){
String line;
while((line = reader.readLine()) != null){
System.out.println(line);
Files.write(file, line.getBytes(), StandardOpenOption.WRITE);
}
}
}
}
Decrypt: read in the key and decrypt it
public class decrypt {
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException {
try {
File fileDir = new File("C:/Users/JT/Desktop/key.txt");
BufferedReader in = new BufferedReader(
new InputStreamReader(new FileInputStream(fileDir), "UTF-8"));
String str;
while ((str = in.readLine()) != null) {
System.out.println(str);
}
in.close();
}
catch (UnsupportedEncodingException e)
{
System.out.println(e.getMessage());
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
byte[] decodedKey = Base64.getDecoder().decode(sb.toString());
SecretKey originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
SecretKeySpec key = new SecretKeySpec(sb.toString().getBytes(), "Base64");
Cipher desalgCipher;
desalgCipher = Cipher.getInstance("AES");
desalgCipher.init(Cipher.DECRYPT_MODE, key);
Path path = Paths.get("encrypted.txt"); // path to your file
try(InputStream is = Files.newInputStream(path); // get an IS on your file
CipherInputStream cipherIS = new CipherInputStream(is, desalgCipher); // wraps stream using cipher
BufferedReader reader = new BufferedReader(new InputStreamReader(cipherIS));){ // init reader.
String line;
while((line = reader.readLine()) != null){
System.out.println(line);
}
}
}
}
回答1:
Your application is not being programmed the right way. Currently you try to encrypt by wrapping the input stream with a CipherInputStream
instance. Then this instance again is wrapped with a BufferedReader
instance.
So what you are doing is to first convert the bytes of the input file - probably text - into ciphertext. This ciphertext can contain any byte value. Then you try to read those bytes in line-by-line using the default character set and line endings. Obviously after encryption even the notion of lines doesn't exist anymore, so you'll loose data in that final step.
Then you convert back to bytes, which you then (somehow) try to decrypt. This will obviously fail as you lost data during the readLine
statement.
What you should do is to read in the file using bytes. You can then write to a CipherOutputStream
. If the file with the ciphertext needs to be actual text you can use a Base64
stream which the new java.util.Base64
nicely provides.
Only once you programmed the encryption correctly you can try and reverse the process. As long as data is lost obviously the decryption will fail (with an error or garbage output, depending on the mode and your luck).
If you're unlucky you will end up with code that works 99% of the time. So good luck and heed the comments: don't try and perform encryption without understanding what you're doing. It will end with tears - or a smashed keyboard.
来源:https://stackoverflow.com/questions/45133268/java-decrypt-a-file-with-base64