在Java中解密文件并将其导出为文件而不进入无限循环?

在Java中解密文件并将其导出为文件而不进入无限循环?,java,encryption,fileinputstream,Java,Encryption,Fileinputstream,如果有多个用户和密码,如何在java中解密文件并将其导出到文件,而不必以无限循环结束?这是我的代码,最后是我的测试文件: import java.io.*; import java.security.*; import java.util.ArrayList; import javax.crypto.*; public class Checker { private ArrayList<String> usersList = new ArrayList<String&

如果有多个用户和密码,如何在java中解密文件并将其导出到文件,而不必以无限循环结束?这是我的代码,最后是我的测试文件:

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 checker = new Checker();
        checker.add("peter", "12345");
        checker.add("mike", "67890");
        checker.display();
        checker.save();
        checker.check();
    }
}
import java.io.*;
导入java.security.*;
导入java.util.ArrayList;
导入javax.crypto.*;
公共类检查器{
private ArrayList usersList=new ArrayList();
私有ArrayList密码列表=新ArrayList();
私有密码=null;
私钥生成器keyGen=null;
私钥=null;
私有打印流输出=System.out;
私有文件输出流fos=null;
检查器(){
试一试{
cipher=cipher.getInstance(“AES”);
keyGen=KeyGenerator.getInstance(“AES”);
key=keyGen.generateKey();
输出=新的打印流(新文件输出流(“data.txt”),true;
fos=新文件输出流(新文件(“data.txt”);
}捕获(无算法异常){
e、 printStackTrace();
}捕获(无此填充例外){
e、 printStackTrace();
}catch(filenotfounde异常){
e、 printStackTrace();
}
}
公共作废检查(){
试一试{
CipherInputStream cipherIn=新CipherInputStream(新文件输入流(新文件(“data.txt”)),cipher;
cipher.init(cipher.DECRYPT_模式,密钥);
int i;
而((i=cipherIn.read())!=-1){
fos.编写(i);
}
output.close();
}catch(filenotfounde异常){
System.err.println(“未找到文件路径!”);
}捕获(IOE异常){
System.err.println(“IOException:+e”);
}捕获(InvalidKeyException e){
e、 printStackTrace();
}
}
public void add(字符串用户、字符串密码){
if(!(usersList.contains(user)| | passwordList.contains(password))){
if(usersList.isEmpty()| | passwordList.isEmpty()){
usersList.clear();
passwordList.clear();
usersList.add(用户);
密码列表。添加(密码);
}否则{
添加(usersList.size(),user);
添加(usersList.size()-1,密码);
}
}
}
公共空间显示(){
System.out.println(usersList);
System.out.println(密码列表);
}
公共作废保存(){
试一试{
对于(int x=0;x

我知道我的
check()
方法不能完全工作(它实际上不会检查它们是否在列表中),但我只需要解密文件,而不是将加密的数据与解密的数据混在一起。

关于代码的一些备注:

  • 不要存储明文密码。。。只是
  • 你为什么这样做:

    添加(usersList.size(),user); 添加(usersList.size()-1,密码)

    老实说,我不明白。为什么不将.add()添加到相应的列表中

  • 为什么在检查列表是否已为空的情况下,还要.clear()清除列表

  • 为什么不让两个用户拥有相同的密码
  • 对于您的出口问题(我认为适应它不会太难):


    从这里开始:

    关于代码的一些提示:

    • 插入说明你为什么做事的注释(以帮助你以后维护/理解)
    • 为现在复制的“AES”和“data.txt”等神奇字符串定义
      private final
      常量(打字错误的可能性较小,如果需要更容易更改)
    • 尽可能使用基类型隐藏实现细节,即
      List usersList
    • 您也可以创建一个
      Map
      来存储用户名的密码,而不是试图保持usersList和passwordsList的同步

    请不要使用制表符缩进代码。改为使用4个空格。我只是复制并粘贴了它eclipse@Tamer-那不是借口。您可以轻松地将Eclipse配置为使用空格而不是制表符。@Stephen C-如果默认Eclipse设置是使用制表符而不是空格,这是一个借口。使用代码块索引的快速按钮时,SO标记编辑器会自动将制表符转换为空格。或者至少在某一点上,我的日食只吐出空格,我懒得去检查。是的,我注意到了。但这不是一件奇怪的事情吗?我的意思是,如果你的密码比用户多,或者反之亦然,那么删除所有东西真的很聪明吗?在上面发布的代码中,如果我没有弄错的话,是不可能遇到这种情况的
     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();