2012-12-11 2 views
3

파일을 압축하는 데 문제가 있습니다. 내가 만들고있는 응용 프로그램을 사용하면 파일 그룹에 암호를 추가 할 수 있으며 해당 파일은 DES로 암호화 (AES로 변경 중) 한 다음 폴더에 저장됩니다. 그러나 암호화되고 암호로 보호 된 후에 암호를 지우는 방법은 무엇입니까? 암호화가 쉽게 시작되는 부분을 지정했습니다.암호화 된 파일을 Java로 압축합니다.

package gui; 
    import java.awt.BorderLayout; 
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    import java.awt.event.MouseAdapter; 
    import java.awt.event.MouseEvent; 
    import java.io.File; 
    import java.io.FileInputStream; 
    import java.io.FileOutputStream; 
    import java.io.IOException; 
    import java.io.InputStream; 
    import java.io.OutputStream; 
    import java.security.AlgorithmParameters; 
    import java.security.spec.KeySpec; 

    import javax.crypto.Cipher; 
    import javax.crypto.CipherInputStream; 
    import javax.crypto.CipherOutputStream; 
    import javax.crypto.SecretKey; 
    import javax.crypto.SecretKeyFactory; 
    import javax.crypto.spec.IvParameterSpec; 
    import javax.crypto.spec.PBEKeySpec; 
    import javax.crypto.spec.SecretKeySpec; 
    import javax.swing.ImageIcon; 
    import javax.swing.JFileChooser; 
    import javax.swing.JMenuItem; 
    import javax.swing.JOptionPane; 
    import javax.swing.JPanel; 
    import javax.swing.JPopupMenu; 
    import javax.swing.JScrollPane; 
    import javax.swing.JTable; 
    import javax.swing.table.DefaultTableModel; 

    public class FileTable extends JPanel { 

     /** 
     * 
     */ 
     private static final long serialVersionUID = 1L; 
     private JTable table; 
     private DefaultTableModel tableModel = new DefaultTableModel(new String[] {"File", "Size", "Status" }, 0); 
     private File dir; 
     private File temp; 
     private JPopupMenu popup; 
     private String key; 
     private PasswordStorage passwordStorage; 
     private JFileChooser fileChooser; 
     private static String salt = "loquetdeliciouslysalty"; 
     private static byte[] IV; 

     public FileTable() { 

      // Set Layout Manager 
      setLayout(new BorderLayout()); 

      // Create Swing Components 
      table = new JTable(); 
      table.setModel(tableModel); 
      table.setDropTarget(new TableDnD(table)); 
      table.setShowGrid(false); 
      table.setFillsViewportHeight(true); 
      table.getColumnModel().getColumn(0).setPreferredWidth(250); 

      passwordStorage = new PasswordStorage(); 
      fileChooser = new JFileChooser(); 
      popup = new JPopupMenu(); 

      JMenuItem removeItem = new JMenuItem("Remove"); 
      removeItem.setIcon(new ImageIcon("removeMenu.png")); 
      popup.add(removeItem); 

      // Add Components to pane 
      add(new JScrollPane(table), BorderLayout.CENTER); 

      table.addMouseListener(new MouseAdapter() { 
       public void mousePressed(MouseEvent e) { 
        int row = table.rowAtPoint(e.getPoint()); 
        table.getSelectionModel().setSelectionInterval(row, row); 

        if(e.getButton() == MouseEvent.BUTTON3) { 
         popup.show(table, e.getX(), e.getY()); 
        } 
       } 
      }); 

      removeItem.addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent arg0) { 
        int row = table.getSelectedRow(); 
        if(row > -1) { 
         tableModel.removeRow(table.getSelectedRow()); 
        } 
       } 
      }); 
     } 

     public boolean isTableEmpty() { 

      if(tableModel.getRowCount() == 0) { 
       return true; 
      } 
      else { 
       return false; 
      } 
     } 

     public void addFile(File file) { 
      tableModel.addRow(new Object[]{file, file.length() + " kb","Not Processed"}); 
     } 

     public void removeFile() { 
      int[] rows = table.getSelectedRows(); 

      for(int i = 0; i < rows.length; i++) { 
       tableModel.removeRow(rows[i]-i); 
      } 
     } 

     public void clearTable() 
     { 
      int rowCount = tableModel.getRowCount(); 

      for(int i = 0; i < rowCount; i++) { 
       tableModel.removeRow(0); 
      } 

      table.removeAll(); 
     } 

     public void encrypt() { 

      if(!isTableEmpty()) { 
       try { 
        do { 
         key = JOptionPane.showInputDialog(this, 
           "Enter password", "Password", 
           JOptionPane.OK_OPTION|JOptionPane.PLAIN_MESSAGE); // key needs to be at least 8 characters for DES 

         if(key == null) break; 
        } while(key.length() < 8); 

        // If OK and length of password >= 8 encrypt files 
        if(key != null) { 

         // Store password 
         passwordStorage.write(key); 

         // Custom Folder for encrypted files 
         fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 

         if(fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) { 
          dir = fileChooser.getSelectedFile(); 
         } 

         else { 
          // Default Folder for decrypted files 
          dir = new File("encrypted"); 
          dir.mkdir(); 
         } 

         for(int i = 0; i < tableModel.getRowCount(); i++) { 
          temp = (File) tableModel.getValueAt(i, 0); 

          FileInputStream fis2 = new FileInputStream(temp); 
          FileOutputStream fos2 = new FileOutputStream(dir + "\\" + (temp.getName())); 

          encrypt(key, fis2, fos2); 
         } 

         for(int i = 0; i < tableModel.getRowCount(); i++) { 
          File toDelete = (File) tableModel.getValueAt(i, 0); 
          toDelete.delete(); 
         } 

         // Encryption complete message 
         JOptionPane.showMessageDialog(this, "Files encrypted succesfully!"); 

         // CLEAR LIST 
         table.removeAll(); 
         clearTable(); 
        } 
       } catch (Throwable te) { te.printStackTrace(); } 
      } 
     } 

     public void decrypt() { 

      if(!isTableEmpty()) { 
       try { 

        key = JOptionPane.showInputDialog(this, 
          "Enter password", "Password", 
          JOptionPane.OK_OPTION|JOptionPane.PLAIN_MESSAGE); 

        while(!passwordStorage.isPassword(key)) { 
         key = JOptionPane.showInputDialog(this, 
           "Enter password", "Wrong Password!", 
           JOptionPane.OK_OPTION|JOptionPane.ERROR_MESSAGE); 
        } 

        // If OK and length of password >= 8 decrypt files 
        if(key != null) { 

         // Custom Folder for decrypted files 
         fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 

         if(fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) { 
          dir = fileChooser.getSelectedFile(); 
         } 

         else { 
          // Default Folder for decrypted files 
          dir = new File("decrypted"); 
          dir.mkdir(); 
         } 

         for(int i = 0; i < tableModel.getRowCount(); i++) { 
          temp = (File) tableModel.getValueAt(i, 0); 

          FileInputStream fis2 = new FileInputStream(temp); 
          FileOutputStream fos2 = new FileOutputStream(dir + "\\" + (temp.getName())); 

          decrypt(key, fis2, fos2); 
         } 

         for(int i = 0; i < tableModel.getRowCount(); i++) { 
          File toDelete = (File) tableModel.getValueAt(i, 0); 
          toDelete.delete(); 
         } 

         // Encryption complete message 
         JOptionPane.showMessageDialog(this, "Files decrypted succesfully!"); 

         // CLEAR LIST 
         table.removeAll(); 
         clearTable(); 
        } 
       } catch (Throwable te) { te.printStackTrace(); } 
      } 
     } 


     /************************************************************************************************************* 
     *  ENCRYPTION METHODS *********************************************************************************** 
     *************************************************************************************************************/ 
     public static void encrypt(String key, InputStream is, OutputStream os) throws Throwable { 
      encryptOrDecrypt(key, Cipher.ENCRYPT_MODE, is, os); 
     } 

     public static void decrypt(String key, InputStream is, OutputStream os) throws Throwable { 
      encryptOrDecrypt(key, Cipher.DECRYPT_MODE, is, os); 
     } 

     public static void encryptOrDecrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable { 

      char[] kgen = key.toCharArray(); 
      byte[] ksalt = salt.getBytes(); 

      SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
      KeySpec spec = new PBEKeySpec(kgen, ksalt, 65536, 256); 
      SecretKey tmp = factory.generateSecret(spec); 
      SecretKey aesKey = new SecretKeySpec(tmp.getEncoded(), "AES"); 
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 


      /*DESKeySpec dks = new DESKeySpec((salt + key).getBytes()); 
      SecretKeyFactory skf = SecretKeyFactory.getInstance("DES"); 
      SecretKey desKey = skf.generateSecret(dks); 
      Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for SunJCE*/ 

      if (mode == Cipher.ENCRYPT_MODE) { 
       cipher.init(Cipher.ENCRYPT_MODE, aesKey); 
       CipherInputStream cis = new CipherInputStream(is, cipher); 
       AlgorithmParameters params = cipher.getParameters(); 
       byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV(); 
       saveIv(iv); 
       doCopy(cis, os); 
      } else if (mode == Cipher.DECRYPT_MODE) { 
       cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(getIv())); 
       CipherOutputStream cos = new CipherOutputStream(os, cipher); 
       doCopy(is, cos); 
      } 
     } 

     public static void saveIv(byte[] iv) { 
      IV = iv; 
     } 

     public static byte[] getIv() { 
      return IV; 
     } 

     public static void doCopy(InputStream is, OutputStream os) throws IOException { 

      byte[] bytes = new byte[1024]; 
      int numBytes; 

      while ((numBytes = is.read(bytes)) > 0) { 
       os.write(bytes, 0, numBytes); 
      } 

      os.flush(); 
      os.close(); 
      is.close(); 
     } 

    } 

답변

4

한 가지 말로, 이벤트 처리 후 암호화를 수행하기 위해 invokeLater을 보지 못했습니다.

  1. GZipOutputStream을 먼저 압축하면 .txt 파일이 .txt.gz 파일로 변환됩니다.
  2. 암호화
  3. 우편 setMethod(ZipOutputStream.STORED)

하여, 비 압축 한 파일 ZipOutputStream이를 갖도록하면 교체

   for(int i = 0; i < tableModel.getRowCount(); i++) { 
        temp = (File) tableModel.getValueAt(i, 0); 
        FileInputStream fis2 = new FileInputStream(temp); 
        FileOutputStream fos2 = new FileOutputStream(dir + "\\" 
          + (temp.getName())); 
        encrypt(key, fis2, fos2); 
       } 

파이프 (입력 접속 및 사용

   // Zip 
       ZipOutputStream zipOut = ... 
       zipOut.setMethod(ZipOutputStream.STORED); // No compression. 

       for(int i = 0; i < tableModel.getRowCount(); i++) { 
        // Single file 
        File originalFile = (File) tableModel.getValueAt(i, 0); 
        FileInputStream originalStream = new FileInputStream(originalFile); 

        // GZipped single file: 
        GZipOutputStream gzipOut = ...; ... 

        // Input of the gzipped thing 
        InputStream gzipResultIn = ... 


        // Make a new ZipEntry: 
        ZipEntry zipEntry = new ZipEntry(originalFile.getName() 
          + ".gz.enc"); 
        zipOut.putNextEntry(zipEntry); 
        encrypt(key, gzipResultIn, zipOut); // Should not close the input 
        zipOut.closeEntry(); 
       } 

       zipOut.close(); 

하여 출력, PipedInputSt ream, PipedOutputStream)을 사용하는 것이 더 좋을 것입니다. 하지만 먼저 ByteArrayOutputStream, ByteArrayInputStream을 시도하거나 임시 파일을 작성한 것처럼 시도 할 수 있습니다.

2

. 반면 암호화는 무작위와 구별 할 수없는 암호문을 생성합니다. 따라서이 데이터를 압축 할 수 없을 가능성이 매우 높습니다. 대신 암호화 전에 데이터를 압축해야합니다.

관련 문제