java - PBKDF2 जावा में बाउंससाइकल के साथ




bouncycastle jce (2)

मैं एक डेटाबेस में पासवर्ड को सुरक्षित रूप से संग्रहीत करने की कोशिश कर रहा हूं और इसके लिए मैंने PBKDF2 फ़ंक्शन का उपयोग करके अपने हैश को स्टोर करने के लिए चुना है। मैं उछालभरी महल पुस्तकालय का उपयोग करना चाहता हूं, लेकिन मुझे नहीं पता कि मैं जेसीई इंटरफेस का उपयोग करके काम करने के लिए इसे क्यों नहीं प्राप्त कर सकता ... समस्या यह है कि 3 अलग-अलग मोड में हैश उत्पन्न करना:
1. सूरज द्वारा प्रदत्त PBKDF2WithHmacSHA1 गुप्त कुंजी कारखाने का उपयोग करना
2. उछालभरी महल एपीआई का सीधे उपयोग करना
3. JCE के माध्यम से उछालभरी महल का उपयोग करना
2 अलग-अलग मूल्यों में परिणाम: पहले दो के लिए एक सामान्य और तीसरे के लिए एक।

यहाँ मेरा कोड है:

    //Mode 1

    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    KeySpec keyspec = new PBEKeySpec("password".toCharArray(), salt, 1000, 128);
    Key key = factory.generateSecret(keyspec);
    System.out.println(key.getClass().getName());
    System.out.println(Arrays.toString(key.getEncoded()));

    //Mode 2

    PBEParametersGenerator generator = new PKCS5S2ParametersGenerator();
    generator.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(("password").toCharArray()), salt, 1000);
    KeyParameter params = (KeyParameter)generator.generateDerivedParameters(128);
    System.out.println(Arrays.toString(params.getKey()));

    //Mode 3

    SecretKeyFactory factorybc = SecretKeyFactory.getInstance("PBEWITHHMACSHA1", "BC");
    KeySpec keyspecbc = new PBEKeySpec("password".toCharArray(), salt, 1000, 128);
    Key keybc = factorybc.generateSecret(keyspecbc);
    System.out.println(keybc.getClass().getName());
    System.out.println(Arrays.toString(keybc.getEncoded()));
    System.out.println(keybc.getAlgorithm());

मुझे पता है कि PBKDF2 को HMAC SHA1 का उपयोग करके कार्यान्वित किया गया है, इसीलिए मैंने अंतिम विधि "PBEWITHHMACSHA1" में एल्गोरिथ्म के रूप में चुना है, जो मैंने उछाल वाले महल जावा डॉक्स से लिया था।

आउटपुट निम्नलिखित है:

com.sun.crypto.provider.SunJCE_ae
[-53, 29, 113, -110, -25, 76, 115, -127, -64, 74, -63, 102, 75, 81, -21, 74]
[-53, 29, 113, -110, -25, 76, 115, -127, -64, 74, -63, 102, 75, 81, -21, 74]
org.bouncycastle.jce.provider.JCEPBEKey
[14, -47, -87, -16, -117, -31, 91, -121, 90, -68, -82, -31, -27, 5, -93, -67, 30, -34, -64, -40]
PBEwithHmacSHA

कोई विचार?


PBKDF2WithHmacSHA1 पहले से ही BouncyCastle 1.60 में समर्थित है

https://www.bouncycastle.org/specifications.html //www.b Councilycastle.org/specifications.html पासवर्ड हैशिंग और PBE

ओपनजेडके रनटाइम एनवायरनमेंट 18.9 (बिल्ड 11.0.1 + 13) के साथ टेस्ट पास किया गया:

    Security.addProvider(new BouncyCastleProvider());

    String password = "xrS7AJk+V6L8J?B%";
    SecureRandom rnd = new SecureRandom();
    int saltLength = 16;
    int keyLength = 128;
    int iterationCount = 10000;

    byte[] salt = new byte[saltLength];
    rnd.nextBytes(salt);

//SunJCE
    SecretKeyFactory factorySun = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1", "SunJCE");
    KeySpec keyspecSun = new PBEKeySpec(password.toCharArray(), salt, iterationCount, keyLength);
    SecretKey keySun = factorySun.generateSecret(keyspecSun);
    System.out.println(keySun.getClass().getName());
    System.out.println(Hex.toHexString(keySun.getEncoded()));

//BouncyCastle  
    SecretKeyFactory factoryBC = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1", "BC");
    KeySpec keyspecBC = new PBEKeySpec(password.toCharArray(), salt, iterationCount, keyLength);
    SecretKey keyBC = factoryBC.generateSecret(keyspecBC);
    System.out.println(keyBC.getClass().getName());
    System.out.println(Hex.toHexString(keyBC.getEncoded()));

    Assert.assertArrayEquals(keySun.getEncoded(), keyBC.getEncoded());

आउटपुट है:

com.sun.crypto.provider.PBKDF2KeyImpl
e9b01389fa91a6172ed6e95e1e1a2611
org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey
e9b01389fa91a6172ed6e95e1e1a2611

मुझे बीसी क्रिप्टो-ओनली विधि (वास्तव में बीसी के सेमी पैकेज से) मिली, जो यूटीएफ -8 आधारित पासवर्ड एन्कोडिंग का उत्पादन करने के लिए काम करती है। इस तरह मैं केडीएफ आउटपुट उत्पन्न कर सकता हूं जो संगत है

http://packages.python.org/passlib/lib/passlib.hash.cta_pbkdf2_sha1.html#passlib.hash.cta_pbkdf2_sha1

private byte[] calculatePasswordDigest(char[] pass, byte[] salt, int iterations)
    throws PasswordProtectionException
{
    try
    {
        /* JCE Version (does not work as BC uses PKCS12 encoding)
        SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWITHHMACSHA1","BC");
        PBEKeySpec ks = new PBEKeySpec(pass, salt, iterations,160);
        SecretKey digest = kf.generateSecret(ks);
        return digest.getEncoded();
        */
        PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
        gen.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(pass), salt, iterations);
        byte[] derivedKey = ((KeyParameter)gen.generateDerivedParameters(160)).getKey();
        return derivedKey;
    }
    catch(Exception e)
    {
        LOG.error("Failed to strengthen the password with PBKDF2.",e);
        throw new PasswordProtectionException();
    }
}




pbkdf2