c# - सी#में हैश पासवर्ड? Bcrypt/PBKDF2




.net hash (5)

PBKDF2

आप वास्तव में वास्तव में करीब थे। आपके द्वारा दिया गया लिंक आपको दिखाता है कि आप PBKDF2 हैश परिणाम प्राप्त करने के लिए Rfc2898DeriveBytes फ़ंक्शन को कैसे कॉल कर सकते हैं। हालांकि, आपको इस तथ्य से फेंक दिया गया था कि उदाहरण एन्क्रिप्शन प्रयोजनों के लिए व्युत्पन्न कुंजी का उपयोग कर रहा था (पीबीकेडीएफ 1 और 2 के लिए मूल प्रेरणा "कुंजी" व्युत्पन्न कार्यों को एन्क्रिप्शन कुंजी के रूप में उपयोग करने के लिए उपयुक्त बनाना था)। बेशक, हम एन्क्रिप्शन के लिए आउटपुट का उपयोग नहीं करना चाहते हैं, बल्कि एक हैश के रूप में।

यदि आप पीबीकेडीएफ 2 चाहते हैं तो आप इस उद्देश्य के लिए लिखी गई SimpleCrypto.Net लाइब्रेरी को आजमा सकते हैं। यदि आप कार्यान्वयन को देखते हैं, तो आप देख सकते हैं कि यह वास्तव में बस एक पतली आवरण है (आपने अनुमान लगाया है) Rfc2898DeriveBytes 9 Rfc2898DeriveBytes

BCrypt

यदि आप इस संस्करण के साथ प्रयोग करना चाहते हैं तो आप सी # कार्यान्वयन नाम (और क्या) BCrypt.NET प्रयास कर सकते हैं।

अस्वीकरण: मैंने उन पुस्तकालयों का उपयोग या परीक्षण नहीं किया है जिन्हें मैंने लिंक किया है ... YMMV

मैंने एमएसडीएन और अन्य संसाधनों को देखा कि यह कैसे करें लेकिन मैं बिना किसी स्पष्ट समाधान के आया हूं। यह सबसे अच्छा है मैंने पाया http://blogs.msdn.com/b/shawnfa/archive/2004/04/14/generating-a-key-from-a-password.aspx?Redirected=true

मैं या तो bcrypt या PBKDF2 (जो संबंधित bcrypt प्रतीत होता है) का उपयोग कर सी # में हैश पासवर्ड चाहते हैं। मैं प्रयोग करना चाहता हूं कि मेरे कंप्यूटर के पास कितने राउंड हैं जो पासवर्ड है। हालांकि सबकुछ एन्क्रिप्टिंग के बारे में प्रतीत होता है जबकि हर कोई हैशिंग के बारे में बात करता है। मेरे द्वारा इसका निर्धारण नहीं किया जा सकता। मैं एक पासवर्ड कैसे है? ऐसा लगता है कि पीबीकेडीएफ 2 (आरएफसी 28 9 8?) एक यादृच्छिक संख्या जनरेटर है और मैं यह चुनने के लिए गेटबाइट्स (राशि) का उपयोग करता हूं कि मेरे हैश आकार कितना बड़ा है।

मैं उलझन में हूं। मैं bcrypt / PBKDF के साथ एक पासवर्ड कैसे है?


PBKDF2

उदाहरण में Rfc2898DeriveBytes , जब आप लाइन पर जाते हैं "Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes (pwd1, salt1, myIterations); ", के 1 हैश हैश। एन्क्रिप्शन के लिए उदाहरण का कारण यह है कि आरएफसी 28 9 8 डेरिवेट्स को मूल रूप से एन्क्रिप्शन कुंजी बनाने के लिए डिज़ाइन किया गया था।

यदि आप नमक नहीं प्रदान करते हैं, तो आरएफसी 28 9 8 डेरिवेट्स अपने स्वयं के निर्माण बनाएंगे, लेकिन मुझे नहीं पता कि आरएनजीक्रिप्टो सेवा प्रदाता क्रिप्टोग्राफिक रूप से यादृच्छिक होने का बेहतर काम करता है या नहीं।

OWASP के अनुसार ( https://www.owasp.org/index.php/Using_Rfc2898DeriveBytes_for_PBKDF2 ), RFC2898DeriveBytes द्वारा SHA1 के अंतर्निहित उपयोग का अर्थ है कि यह 160 बिट्स तक लम्बाई के लिए केवल अच्छा है। यदि आप एक लंबा हैश बनाते हैं, तो हमलावर को अभी भी पहले 160 बिट्स के बारे में चिंता करने की ज़रूरत है, लेकिन आपने बिना किसी लाभ के अपने पासवर्ड के लिए पासवर्ड हैशिंग / प्रमाणीकरण अधिक महंगा बना दिया है।

Rfc2898DeriveBytes पासवर्ड हैशिंग के लिए कुछ उदाहरण कोड यहां दिया गया है (डीबी में हैश, नमक और पुनरावृत्तियों को स्टोर करें):

public class Rfc2898PasswordEncoder
{
    private int _byteLength = 160 / 8; // 160 bit hash length

    public class EncodedPassword
    {
        public byte[] Hash { get; set; }
        public byte[] Salt { get; set; }
        public int Iterations { get; set; }
    }

    public EncodedPassword EncodePassword(string password, int iterations)
    {
        var populatedPassword = new EncodedPassword
        {
            Salt = CreateSalt(),
            Iterations = iterations
        };

        // Add Hash
        populatedPassword.Hash = CreateHash(password, populatedPassword.Salt, iterations);

        return populatedPassword;
    }

    public bool ValidatePassword(string password, EncodedPassword encodedPassword)
    {
        // Create Hash
        var testHash = CreateHash(password, encodedPassword.Salt, encodedPassword.Iterations);

        return testHash == encodedPassword.Hash;
    }

    public byte[] CreateSalt()
    {
        var salt = new byte[_byteLength]; // Salt should be same length as hash

        using (var saltGenerator = new RNGCryptoServiceProvider())
        {
            saltGenerator.GetBytes(salt);
        }

        return salt;
    }

    private byte[] CreateHash(string password, byte[] salt, long iterations)
    {
        byte[] hash;
        using (var hashGenerator = new Rfc2898DeriveBytes(password, salt, (int)iterations))
        {
            hash = hashGenerator.GetBytes(_byteLength);
        }

        return hash;
    }
} 

काम करने के लिए हैश पासवर्ड प्राप्त करने के लिए वास्तव में कोड को वास्तव में कोड करने के लिए मुझे forever (दिन लग गए) इसलिए मैंने इसे सुविधा के लिए यहां रखा है।

आपको documentation और theory1 theory2 को पढ़ने की आवश्यकता है और फिर कुछ या आप सुरक्षा की कमी के लिए खुले हो सकते हैं। सुरक्षा एक बहुत बड़ा विषय है! सावधान ग्राहक!

समाधान के लिए NuGet पैकेज BCrypt.Net जोड़ें

const int WorkFactor = 14;
var HashedPassword = BCrypt.Net.BCrypt.HashPassword(Password, WorkFactor); 

आपको WorkFactor को उचित रूप से देखने के लिए समायोजित करना चाहिए। यह एक लॉग 2 समारोह है

"संख्या लॉग 2 है, इसलिए प्रत्येक बार जब कंप्यूटर गति में दोगुना हो जाता है, तो डिफ़ॉल्ट संख्या में 1 जोड़ें।"

फिर आप अपने डीबी में हैश पासवर्ड को passwordFromLocalDB रूप में स्टोर करते हैं FROLocalDB और इस तरह आने वाले password का परीक्षण करने के लिए:

if (BCrypt.Net.BCrypt.Verify(password, passwordFromLocalDB) == true)

शुभ लाभ!


पीबीकेडीएफ 2 एचएमएसीएसए 1 का उपयोग करता है, यदि आप अधिक आधुनिक और अनुकूलन समाधान चाहते हैं तो आपको एचपीएसीएसए 256 या 512 का उपयोग करके इस एपीआई को देखना चाहिए जैसे कि पीबीकेडीएफ 2

https://sourceforge.net/projects/pwdtknet/

स्रोत कोड में नमूना जीयूआई ने दिखाया कि क्रिप्टो यादृच्छिक नमक के निर्माण सहित पासवर्ड से हैश कैसे प्राप्त करें ..... आनंद लें :)


मुझे ऐसे उत्तरों में रूचि थी जिसमें किसी भी पुस्तकालय शामिल नहीं थे।

मैंने इस आलेख को https://crackstation.net/hashing-security.htm पढ़ा है जो विभिन्न भाषाओं में एक कार्यान्वयन को जोड़ता है # उनमें से जो मैं यहां भी लिंक करूंगा

https://github.com/defuse/password-hashing/blob/master/PasswordStorage.cs

दिलचस्प रूप से यह आरएफसी 28 9 8 डेरिवेट्स का उपयोग करता है जैसा कि यहां कुछ बार बताया गया है।

private static byte[] PBKDF2(string password, byte[] salt, int iterations, int outputBytes){
    using (var pbkdf2 = new Rfc2898DeriveBytes(password, salt)) {
        pbkdf2.IterationCount = iterations;
        return pbkdf2.GetBytes(outputBytes);
    }
}




bcrypt