java एक चार के साथ BCrypt का उपयोग करना




security hash (3)

लगभग कुछ घंटों पहले, मैंने स्टैक ओवरफ्लो के बारे में पूछताछ की है कि कैसे एक चार [] एक एमडी 5 हैश में कनवर्ट करने के तरीकों के बारे में। एक समाधान प्रदान किया गया था, लेकिन असुरक्षित माना गया था - जैसा कि कुछ लोगों द्वारा उल्लिखित किया गया है: एक एमडी 5 हैश को एक चार से उत्पन्न करना []

नील स्मिथलाइन ने सिफारिश की कि मैं बीसीरीपेट का उपयोग कर रहा हूं, लेकिन मैं इसे चार [] के साथ उपयोग करने में असमर्थ हूं

इसका कारण है कि मैं लॉगिन प्रपत्र से पुनर्प्राप्त किए गए पासवर्ड को संग्रहीत करने के लिए एक चार [] का उपयोग कर रहा हूँ क्योंकि .getPassword() केवल चार का समर्थन करता है []

        char[] passwordChars = passwordInputField.getPassword();
        String hashed = BCrypt.hashpw(passwordChars, BCrypt.gensalt(12));

वर्तमान में, मैं एक हैश उत्पन्न करने के लिए उपरोक्त कोड का उपयोग करने की कोशिश कर रहा हूं, लेकिन चर पासवर्ड के रूप में BCrypt.haspw() एक प्रकार का है [], यह BCrypt.haspw() द्वारा समर्थित नहीं है

अब एकमात्र कारण है कि मैं एक नियमित स्ट्रिंग का उपयोग क्यों नहीं कर रहा हूं क्योंकि यह स्मृति से साफ नहीं किया जा सकता है

मेरा प्रश्न अब है - क्या बीआरक्रिप्ट के साथ किसी तरह का उपयोग करना संभव है?

अग्रिम में धन्यवाद!


इसलिए, https://github.com/jeremyh/jBCrypt पर प्रस्तुत किए गए कार्यान्वयन के आधार पर, आपको String बजाय char[] स्वीकार करने के लिए hashpw और checkpw तरीकों को बदलने की जरूरत है

शायद, सबसे कठिन हिस्सा hashpw ...

    try {
        passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8");
    } catch (UnsupportedEncodingException uee) {
        throw new AssertionError("UTF-8 is not supported");
    }

सबसे आसान समाधान String char[] को String में वापस करना होगा, लेकिन हम उस से बचने की कोशिश कर रहे हैं। इसके बजाय, चार [] से बाइट [] को परिवर्तित करने के उच्चतम स्कोरिंग के उत्तर के आधार पर हम कुछ और कर सकते हैं ...

    char[] expanded = password;
    if (minor >= 'a') {
        expanded = Arrays.copyOf(expanded, expanded.length + 1);
        expanded[expanded.length - 1] = '\000';
    }

    CharBuffer charBuffer = CharBuffer.wrap(expanded);
    ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
    passwordb = Arrays.copyOfRange(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit());

checkpw विधि को वास्तव में किसी भी संशोधन (पैरामीटर से अलग) की आवश्यकता नहीं है, क्योंकि यह परिणामों की जांच करने के लिए hashpw विधि का उपयोग करता है।

तो, परीक्षण ...

// We want the same salt for comparison
String salt = BCrypt.gensalt(12);
String original = BCrypt.hashpw("Testing", salt);
System.out.println(original);
String hash = BCrypt.hashpw("Testing".toCharArray(), salt);
System.out.println(hash);
System.out.println(BCrypt.checkpw("Testing", hash));
System.out.println(BCrypt.checkpw("Testing".toCharArray(), hash));

आउटपुट ...

$2a$12$KclXlnca78yhcrg1/mNrRepLYqeJE//SRhrh1X3UM7YUQMjY4x8gy
$2a$12$KclXlnca78yhcrg1/mNrRepLYqeJE//SRhrh1X3UM7YUQMjY4x8gy
true
true

अब, अगर आपके पास एक GitHub खाता है, तो आप वास्तव में मूल रिपो को क्लोन कर सकते हैं, सुझाए गए परिवर्तनों को बना सकते हैं और पुल अनुरोध जनरेट कर सकते हैं। मैं, व्यक्तिगत रूप से checkpw - hashpw और hashpw विधियों से छुटकारा पाने के लिए checkpw hashpw जिसमें String आवश्यकता होती है

मुझे यह भी PDKDF2 का कार्यान्वयन मिला, जो String का उपयोग करता है, लेकिन फिर उसे तत्काल एक char[] कनवर्ट किया गया ... इसलिए, यह बहुत ही बदलना था ...


आपके प्रश्न का संक्षिप्त जवाब: हाँ , जावा में BCrypt के साथ char[] का उपयोग करना संभव है

जावा के लिए उछालभरी कैसल क्रिप्टो संकुल संस्करण 1.52 (मार्च 2015) में बीसीआरिप पासवर्ड हैशिंग एल्गोरिदम (स्ट्रिंग फॉर्मेट का उपयोग करके और ओपन बीएसडीए पर संदर्भ कार्यान्वयन के बेस 64 एन्कोडिंग) को जोड़ा गया है, और यह केवल char[] पासवर्ड का समर्थन करता है

एक BCrypt स्ट्रिंग उत्पन्न करने के लिए प्रासंगिक विधि org.bouncycastle.crypto.generators में पाई जा सकती है OpenBSDBCrypt वर्ग और निम्न हस्ताक्षर हैं:

String generate(char[] password,
                byte[] salt,
                int cost)

यदि आप स्रोत कोड में सत्यापित करना चाहते हैं कि char[] को स्ट्रिंग में परिवर्तित किए बिना संरक्षित किया गया है, तो संबंधित कक्षाएं ओपनबीएसडीबीक्रिप्ट , स्ट्रिंग्स और बीक्रिप्ट हैं


दोनों जावा क्रिप्ट की impls है कि मैं इनपुट के रूप में एक स्ट्रिंग ले पाया। जैसा कि आप जानते हैं, पासवर्ड को स्ट्रिंग में डालने से आपको स्मृति हमले तक खुल जाता है।

आप पीबीकेडीएफ 2 और साथ ही बीक्रीप का उपयोग कर सकते हैं। दोनों शीर्ष पायदान माना जाता है यहां और यहां पीबीकेडीएफ 2 जावा कोड नमूने हैं । दोनों कार्यों के लिए एक char[] पारित करने की अनुमति

टिप्पणियों से एक अंतर्निहित प्रश्न का उत्तर देने के लिए, आप MD5 या किसी भी हैश का उपयोग नहीं करने का कारण यह है कि वे अभी बहुत तेज़ हैं जानवरों के साथ विशेष हार्डवेयर के साथ मजबूर पासवर्ड उनके साथ संभव हो जाता है बीसीआरपीटी और पीबीकेडीएफ 2 धीमे होने के लिए डिज़ाइन किए गए हैं।

यहां तक ​​कि अगर आप एक हैश (जो मैं के खिलाफ सुझाता है) का उपयोग करने जा रहे हैं, तो आपको इसे नमक करना चाहिए अनसाल्टेड पासवर्ड हैशेज़ को बदलना तुच्छ है ( यह उपकरण देखें)।

पासवर्ड संग्रहण पर क्रैकस्टेशन का संदर्भ एक अच्छा सामान्य संदर्भ है।





bcrypt