Расшифровывать файл в Java и экспортировать его в файл, не заходя в бесконечные циклы? - PullRequest
0 голосов
/ 26 декабря 2009

Как вы расшифровываете файл в 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();
    }
}

Я знаю, что мой метод check() не работает полностью (он фактически не проверяет, есть ли они в списке), но мне просто нужно расшифровать файл, а не зашифровать с расшифрованными данными все перепутали.

Ответы [ 2 ]

1 голос
/ 26 декабря 2009

Несколько подсказок к вашему коду:

  • вставьте комментарии, которые описывают, почему вы делаете что-то (чтобы помочь вам сохранить / понять это позже)
  • определить private final константы для магических строк, таких как "AES" и "data.txt", которые копируются повсеместно (меньше шансов на опечатки и легче изменить при необходимости)
  • использовать базовые типы, скрывая детали реализации, где это возможно, т.е. List<String> usersList
  • вместо того, чтобы пытаться синхронизировать usersList и passwordsList, вы также можете создать Map<<String>,<String>> для хранения паролей для имен пользователей.
0 голосов
/ 26 декабря 2009

Некоторые замечания по вашему коду:

  1. Не храните незашифрованные пароли ... это просто плохо .
  2. Почему вы это делаете:

    usersList.add (usersList.size (), user); passwordList.add (usersList.size () - 1, пароль);

    Честно говоря, я не понимаю. Почему бы вам просто не добавить .add () в соответствующий список?

  3. Почему вы .clear () списки, когда вы проверили до того, что они уже пусты?

  4. Почему вы не разрешите двум пользователям использовать один и тот же пароль?

Для вашей проблемы с экспортом (я думаю, ее не составит труда адаптировать):

 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();

Отсюда: http://www.java2s.com/Tutorial/Java/0490__Security/UsingCipherOutputStream.htm

...