2009-06-18 156 views
6

我想知道是否有人試圖做的相當於Java的C#Rfc2898DerivedBytes

Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(secret, saltValueBytes); 
byte[] secretKey = key.GetBytes(16); 

Java中的等價物。如果secret是一個字符串(密碼),saltValueBytes就是字節數組中的一個鹽。

我試過的東西,但似乎無法包裹我的頭。

+0

你能告訴你如何解決它與所選答案中的庫? – 2015-10-08 09:02:32

回答

4

我發現this implementation通過谷歌搜索,但我從來沒有用過它。

RFC 2898 /PKCS#的一個免費的Java實現5 PBKDF2

似乎有不小的,自由 可用的Java實現的RFC 2898/PKCS#5可用。小在 只有幾個源文件,與微不足道的 編譯和沒有依賴關係,在LGPL免費爲 。

鑑於HMACSHA1的可用性 標準SUN JCE加密 提供商,這樣的實現是 相當簡單,並且可以從 毫不誇張地被導出的RFC描述。 我的代碼是一個潔淨室實現 只有RFC作爲其基礎。

+0

謝謝,安德魯。不是我正在尋找的東西,因爲我真的很喜歡使用普通庫的常規Java實現 – 2009-06-19 09:06:20

+0

我知道它 - 真的很無助,沒有直接的等價物。 – 2009-06-19 17:47:44

+0

@ElChe我知道這是舊的,但既然你選擇這個作爲答案,你能告訴你最終是如何寫出與你詢問的2行(使用鏈接的實現)等價的嗎? – 2015-09-29 13:29:38

4

這一個適合我。 我仍然不相信在JRE中不存在符合RFC2898標準的PBKDF2的標準實現。我想我一定是在錯誤的地方看。名稱混淆(RFC2898 PKCS5 PBKDF2)沒有幫助。

// PBKDF2.java 
// ------------------------------------------------------------------ 
// 
// RFC2898 PBKDF2 in Java. The RFC2898 defines a standard algorithm for 
// deriving key bytes from a text password. This is also called 
// "PBKDF2", for Password-based key derivation function #2. 
// 
// There's no RFC2898-compliant PBKDF2 function in the JRE, as far as I 
// know, but it is available in many J2EE runtimes, including those from 
// JBoss, IBM, and Oracle. 
// 
// It's fairly simple to implement, so here it is. 
// 
// Author: Admin 
// built on host: DINOCH-2 
// Created Sun Aug 09 01:06:57 2009 
// 
// last saved: 
// Time-stamp: <2009-August-09 11:11:47> 
// ------------------------------------------------------------------ 
// 
// code from Matthias Gartner 
// 
// ------------------------------------------------------------------ 

package cheeso.examples; 


import java.security.NoSuchAlgorithmException; 
import java.security.InvalidKeyException; 
import javax.crypto.Mac; 
import javax.crypto.spec.SecretKeySpec; 


public class PBKDF2 
{ 
    public static byte[] deriveKey(byte[] password, 
            byte[] salt, 
            int iterationCount, 
            int dkLen) 
     throws java.security.NoSuchAlgorithmException, 
       java.security.InvalidKeyException 
    { 
     SecretKeySpec keyspec = new SecretKeySpec(password, "HmacSHA1"); 
     Mac prf = Mac.getInstance("HmacSHA1"); 
     prf.init(keyspec); 

     // Note: hLen, dkLen, l, r, T, F, etc. are horrible names for 
     //  variables and functions in this day and age, but they 
     //  reflect the terse symbols used in RFC 2898 to describe 
     //  the PBKDF2 algorithm, which improves validation of the 
     //  code vs. the RFC. 
     // 
     // hLen denotes the length in octets of the pseudorandom function output 
     // dklen the length in octets (bytes) of the derived key. 

     int hLen = prf.getMacLength(); // 20 for SHA1 
     int l = Math.ceil(dkLen/hLen); // 1 for 128bit (16-byte) keys 
     int r = dkLen - (l-1)*hLen;  // 16 for 128bit (16-byte) keys 
     byte T[] = new byte[l * hLen]; 
     int ti_offset = 0; 
     for (int i = 1; i <= l; i++) { 
      F(T, ti_offset, prf, salt, iterationCount, i); 
      ti_offset += hLen; 
     } 

     if (r < hLen) { 
      // Incomplete last block 
      byte DK[] = new byte[dkLen]; 
      System.arraycopy(T, 0, DK, 0, dkLen); 
      return DK; 
     } 
     return T; 
    } 


    private static void F(byte[] dest, int offset, Mac prf, byte[] S, int c, int blockIndex) { 
     final int hLen = prf.getMacLength(); 
     byte U_r[] = new byte[ hLen ]; 
     // U0 = S || INT (i); 
     byte U_i[] = new byte[S.length + 4]; 
     System.arraycopy(S, 0, U_i, 0, S.length); 
     INT(U_i, S.length, blockIndex); 
     for(int i = 0; i < c; i++) { 
      U_i = prf.doFinal(U_i); 
      xor(U_r, U_i); 
     } 

     System.arraycopy(U_r, 0, dest, offset, hLen); 
    } 

    private static void xor(byte[] dest, byte[] src) { 
     for(int i = 0; i < dest.length; i++) { 
      dest[i] ^= src[i]; 
     } 
    } 

    private static void INT(byte[] dest, int offset, int i) { 
     dest[offset + 0] = (byte) (i/(256 * 256 * 256)); 
     dest[offset + 1] = (byte) (i/(256 * 256)); 
     dest[offset + 2] = (byte) (i/(256)); 
     dest[offset + 3] = (byte) (i); 
    } 

    // ctor 
    private PBKDF2() {} 
} 
+0

嗨,如何使用它,它是否支持256鍵?歡呼 – 2011-02-15 08:51:47

1

通過添加過載deriveKey稍微提高Cheeso的用於與HMacSHA256或HMacSHA512工作碼()。通過這種改變,代碼運行於來自
PHP Crypt lib的PKDF2-HMAC-SHA512測試向量,其導致100個測試案例中的6個故障。

// PBKDF2.java 
// ------------------------------------------------------------------ 
// 
// RFC2898 PBKDF2 in Java. The RFC2898 defines a standard algorithm for 
// deriving key bytes from a text password. This is also called 
// "PBKDF2", for Password-based key derivation function #2. 
// 
// There's no RFC2898-compliant PBKDF2 function in the JRE, as far as I 
// know, but it is available in many J2EE runtimes, including those from 
// JBoss, IBM, and Oracle. 
// 
// It's fairly simple to implement, so here it is. 
// 
// Author: Admin 
// built on host: DINOCH-2 
// Created Sun Aug 09 01:06:57 2009 
// 
// last saved: 
// Time-stamp: <2009-August-09 11:11:47> 
// ------------------------------------------------------------------ 
// 
// code from Matthias Gartner 
// 
// ------------------------------------------------------------------ 

package cheeso.examples; 


import java.security.NoSuchAlgorithmException; 
import java.security.InvalidKeyException; 
import javax.crypto.Mac; 
import javax.crypto.spec.SecretKeySpec; 


public class PBKDF2 
{ 
    public static byte[] deriveKey(byte[] password, 
            byte[] salt, 
            int iterationCount, 
            int dkLen) 
      throws NoSuchAlgorithmException, 
      InvalidKeyException 
    { 
     return deriveKey("HmacSHA1", password, salt, iterationCount, dkLen); 
    } 

    public static byte[] deriveKey(String hmacAlgo, 
            byte[] password, 
            byte[] salt, 
            int iterationCount, 
            int dkLen) 
      throws NoSuchAlgorithmException, 
      InvalidKeyException 
    { 
     SecretKeySpec keyspec = new SecretKeySpec(password, hmacAlgo); 
     Mac prf = Mac.getInstance(hmacAlgo); 
     prf.init(keyspec); 

     // Note: hLen, dkLen, l, r, T, F, etc. are horrible names for 
     //  variables and functions in this day and age, but they 
     //  reflect the terse symbols used in RFC 2898 to describe 
     //  the PBKDF2 algorithm, which improves validation of the 
     //  code vs. the RFC. 
     // 
     // dklen is expressed in bytes. (16 for a 128-bit key, 32 for 256) 

     int hLen = prf.getMacLength(); // 20 for SHA1 
     int l = Math.max(dkLen, hLen); // 1 for 128bit (16-byte) keys 
     int r = dkLen - (l-1)*hLen;  // 16 for 128bit (16-byte) keys 
     byte T[] = new byte[l * hLen]; 
     int ti_offset = 0; 
     for (int i = 1; i <= l; i++) { 
      F(T, ti_offset, prf, salt, iterationCount, i); 
      ti_offset += hLen; 
     } 

     if (r < hLen) { 
      // Incomplete last block 
      byte DK[] = new byte[dkLen]; 
      System.arraycopy(T, 0, DK, 0, dkLen); 
      return DK; 
     } 
     return T; 
    } 


    private static void F(byte[] dest, int offset, Mac prf, byte[] S, int c, int blockIndex) { 
     final int hLen = prf.getMacLength(); 
     byte U_r[] = new byte[ hLen ]; 
     // U0 = S || INT (i); 
     byte U_i[] = new byte[S.length + 4]; 
     System.arraycopy(S, 0, U_i, 0, S.length); 
     INT(U_i, S.length, blockIndex); 
     for(int i = 0; i < c; i++) { 
      U_i = prf.doFinal(U_i); 
      xor(U_r, U_i); 
     } 

     System.arraycopy(U_r, 0, dest, offset, hLen); 
    } 

    private static void xor(byte[] dest, byte[] src) { 
     for(int i = 0; i < dest.length; i++) { 
      dest[i] ^= src[i]; 
     } 
    } 

    private static void INT(byte[] dest, int offset, int i) { 
     dest[offset + 0] = (byte) (i/(256 * 256 * 256)); 
     dest[offset + 1] = (byte) (i/(256 * 256)); 
     dest[offset + 2] = (byte) (i/(256)); 
     dest[offset + 3] = (byte) (i); 
    } 

    // ctor 
    private PBKDF2() {} 
} 
4

我知道這是太遲了,但Java 6和高達確實有一個內置的PBKDF2執行。

int dkLen = 64; 
int rounds = 1000; 
PBEKeySpec keySpec = new PBEKeySpec("Some password".toCharArray(), "SomeSalt".getBytes(), rounds, dkLen * 8); 
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
byte[] out = factory.generateSecret(keySpec).getEncoded(); 

Java 6 Security Enhancements索賠可比性與PKCS#5的名單,並通過我自己的(粗略)測試它似乎產生正確的PBKDF2密鑰。