Decrypting a file in Java and exporting it to a file without going into infinite loops?
How do you decrypt a file in java and export it to a file without having to end up in an infinite loop if you have more than one user and password? Here is my code and at the end is my test file:
import java.io.*;
import java.security.*;
import java.util.ArrayList;
import javax.crypto.*;
public class Checker {
private ArrayList<String> usersList = new ArrayList<String>();
private ArrayList<String> passwordList = new ArrayList<String>();
private Cipher cipher = null;
private KeyGenerator keyGen = null;
private Key key = null;
private PrintStream output = System.out;
private FileOutputStream fos = null;
Checker() {
try {
cipher = Cipher.getInstance("AES");
keyGen = KeyGenerator.getInstance("AES");
key = keyGen.generateKey();
output = new PrintStream(new FileOutputStream("data.txt"), true);
fos = new FileOutputStream(new File("data.txt"));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void check() {
try {
CipherInputStream cipherIn = new CipherInputStream(new FileInputStream(new File("data.txt")), cipher);
cipher.init(Cipher.DECRYPT_MODE, key);
int i;
while((i = cipherIn.read()) != -1){
fos.write(i);
}
output.close();
} catch (FileNotFoundException e) {
System.err.println("filepath not found!");
} catch (IOException e) {
System.err.println("IOException: " + e);
} catch (InvalidKeyException e) {
e.printStackTrace();
}
}
public void add(String user, String password) {
if ( !(usersList.contains(user) || passwordList.contains(password))) {
if(usersList.isEmpty() || passwordList.isEmpty()) {
usersList.clear();
passwordList.clear();
usersList.add(user);
passwordList.add(password);
} else {
usersList.add(usersList.size(), user);
passwordList.add(usersList.size() - 1, password);
}
}
}
public void display() {
System.out.println(usersList);
System.out.println(passwordList);
}
public void save() {
try {
for (int x = 0; x < usersList.size(); x++) {
output.print(usersList.get(x));
output.print("|");
output.println(passwordList.get(x));
}
CipherInputStream cipherIn = new CipherInputStream(new FileInputStream(new File("data.txt")), cipher);
cipher.init(Cipher.ENCRYPT_MODE, key);
int i;
while ((i = cipherIn.read()) != -1) {
fos.write(i);
}
output.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
}
}
public class CheckerTest {
public static void main(String[] args) {
Checker che开发者_开发百科cker = new Checker();
checker.add("peter", "12345");
checker.add("mike", "67890");
checker.display();
checker.save();
checker.check();
}
}
I know that my check()
method does not work fully (it doesn't actually check if they are in the list) but I just need to decrypt the file as well as, not to have the encrypted with the decrypted data all mixed up.
A few hints towards your code:
- insert comments that describe why you do things (to help you maintain / understand it later)
- define
private final
constants for the magic strings like "AES" and "data.txt" that are copied all over now (less chance of typoes and easier to change if need be) - use base types hiding implementation details where possible, i.e.
List<String> usersList
- instead of trying to keep the usersList and passwordsList in synch, you could also create a
Map<<String>,<String>>
for storing passwords for usernames.
Some remarks on your code:
- Don't store plaintext passwords... it's just bad.
Why are you doing this:
usersList.add(usersList.size(), user); passwordList.add(usersList.size()-1, password);
Honestly, I don't get it. Why don't you just .add() to the according list?
Why do you .clear() the lists when you have checked before that they are already empty?
- Why won't you let two users have the same password?
For your exporting problem (I think it won't be too hard to adapt it):
KeyGenerator kg = KeyGenerator.getInstance("DES");
kg.init(new SecureRandom());
SecretKey key = kg.generateKey();
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
Class spec = Class.forName("javax.crypto.spec.DESKeySpec");
DESKeySpec ks = (DESKeySpec) skf.getKeySpec(key, spec);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("keyfile"));
oos.writeObject(ks.getKey());
Cipher c = Cipher.getInstance("DES/CFB8/NoPadding");
c.init(Cipher.ENCRYPT_MODE, key);
CipherOutputStream cos = new CipherOutputStream(new FileOutputStream("ciphertext"), c);
PrintWriter pw = new PrintWriter(new OutputStreamWriter(cos));
pw.println("Stand and unfold yourself");
pw.close();
oos.writeObject(c.getIV());
oos.close();
From here: http://www.java2s.com/Tutorial/Java/0490__Security/UsingCipherOutputStream.htm
精彩评论