2012-04-04 68 views
4

我在做Java的應用程序之前,先驗證密碼,我想允許用戶加密文件(或文件夾 - 我壓縮的目錄)使用自己選擇的密碼。目前,我有以下方法(S):PBE:試圖解密

static Cipher createCipher(int mode, String password) throws Exception { 
      PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray()); 
      SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); 
      SecretKey key = keyFactory.generateSecret(keySpec); 
      MessageDigest md = MessageDigest.getInstance("MD5"); 
      md.update("input".getBytes()); 
      byte[] digest = md.digest(); 
      byte[] salt = new byte[8]; 
      for (int i = 0; i < 8; ++i) 
       salt[i] = digest[i]; 
      PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 20); 
      Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES"); 
      cipher.init(mode, key, paramSpec); 
      return cipher; 
    } 

    static void applyCipher(String inFile, String outFile, Cipher cipher) throws Exception { 
      String decryption = ""; 
      CipherInputStream in = new CipherInputStream(new FileInputStream(inFile), cipher); 
      BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outFile)); 
      int BUFFER_SIZE = 8; 
      byte[] buffer = new byte[BUFFER_SIZE]; 
      int numRead = 0; 
      do { 
       numRead = in.read(buffer); 
       System.out.println(buffer + ", 0, " + numRead); 
       if (numRead > 0){ 
       out.write(buffer, 0, numRead); 
       System.out.println(toHexString(buffer, 0, numRead)); 
       } 
      } while (numRead == 8); 
      in.close(); 
      out.flush(); 
      out.close(); 
      } 
    private static char[] hex_table = { 
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
      'a', 'b', 'c', 'd', 'e', 'f'}; 

    public static String toHexString(byte[] data, int offset, int length) 
    { 
     StringBuffer s = new StringBuffer(length*2); 
     int end = offset+length; 

     for (int i = offset; i < end; i++) 
     { 
     int high_nibble = (data[i] & 0xf0) >>> 4; 
     int low_nibble = (data[i] & 0x0f); 
     s.append(hex_table[high_nibble]); 
     s.append(hex_table[low_nibble]); 
     } 

     return s.toString(); 
    } 

然而,爲了使程序更加用戶友好的,我想能夠檢查用戶輸入正確的密碼產生一個文件之前。我不想「離開下的門墊的關鍵」或完全撤消安全等等 - 我只是想阻止錯誤的文件被產生,如果用戶輸入了錯誤的密碼...

任何想法將不勝感激。如果你需要更多的細節,請不要猶豫,問。

在此先感謝

+0

如果我要實現這樣的事情我會壓縮用戶選擇的文件,但我也想補充用於驗證密碼,然後驗證該文件的內容非常小的文件(1個字節)。 – 2012-04-04 14:22:03

回答

2

使用PBKDF2WithHmacSHA1而不是PBEWithMD5AndDES。後來的用戶有兩個不同的過時原語。前者是目前的標準。

你有兩個選擇

  1. 快,但安全性較差: 把短已知值在您的加密文件的開始或相同的密碼加密下一個完全不同的短文件。當你解密這個文件時,檢查已知的值。

    顯然這個工程很快。它的安全性稍差,因爲它意味着攻擊者試圖暴力破解密碼可以更快地丟棄猜測的密碼:而不必查看整個文件,只需檢查該值即可。這並不是一個大問題,因爲你的密鑰派生函數應該足夠硬,而且他們仍然需要運行該密鑰,並且還需要存儲加密文件的哈希值,並在解密時驗證哈希值。 更安全的是攻擊者必須解密整個文件並讀取它,但出於同樣的原因,它很慢。

+0

我知道你不應該這樣做,但我認爲'不那麼沒有安全感'你的意思是'不太安全'!?此外,擴展這些想法,你是否認爲我可以在下面的鏈接上使用該方法來在文件頂部存儲散列版本的密碼以驗證,然後繼續解密文件的其餘部分if密碼是否正確?如果是這樣,那會有多安全? http://www.rgagnon.com/javadetails/java-0400.html謝謝你的回答,尤其是對於原始語/標準! – Andy 2012-04-05 10:40:30

+0

此外,我剛剛嘗試實現該PBKDF2WithHmacSHA1並創建一個密碼,就像我對PBEWithMD5AndDES所做的一樣,但是每次我都會收到一個'InvalidKeySpecException:Salt not found'。任何人都知道爲什麼?我正在使用最新版本的Java/JDK。 – Andy 2012-04-05 18:16:46

+0

是的,我的意思是不那麼安全。提供密碼散列的文件是加密的,當然。事實上,您可以在該點存儲密碼,因爲該文件是安全的。 真的,@ erickson的帖子下面可能是最好的主意,如果你可以得到一個經過驗證的分組密碼操作模式(它在所有Java平臺中都不支持) 我不認爲PBKDF2是PBE的替代品。它需要我認爲不同的參數。我相信這是一個工作示例http://stackoverflow.com/a/992413/980922 – imichaelmiers 2012-04-05 20:20:45

3

您可以使用該文件保存加密的密碼。當用戶輸入密碼時,如果文件中存在相同的加密密碼,則對其進行加密並檢查。如果沒有,你不加載文件。

+0

謝謝你的回答,但我不太明白你的意思。你是說我應該將密碼存儲爲加密文件旁邊的純文本,還是將密碼存儲在帶有固定密碼/算法的加密文件中?請詳細說明/解釋... – Andy 2012-04-04 14:31:29

+0

當用戶給該文件輸入密碼時,將其加密並將其保存在文件中(加密方式相同)。當用戶加載文件時,會提示輸入密碼,對其進行加密並將其與文件中的加密密碼進行比較。所以密碼被存儲在文件中,但被加密。我認爲這就像密碼一樣存儲在Unix中。再次 – 2012-04-04 15:03:15

+0

謝謝,我有種結束了使用這種方法,但現在我在文件上存儲的密碼(你會通過閱讀接受的答案見)。 – Andy 2012-04-06 18:20:33

1

我會使用AEAD模式,如CCM或EAX。這將檢查文件解密時每個塊的完整性,如果密鑰不正確或文件被篡改,則會失敗。 Bouncy城​​堡提供商supports both這些模式。

+0

謝謝您的回答,並對我的回覆缺乏真誠的歉意。我會實施一個AEAD模式,但說實話,我在做什麼(在當時)似乎有點複雜,我接受的答案是最適合我的情況...... +1 – Andy 2012-04-06 18:27:26