मैं वाष्प के auth-template टेम्पलेट (यहां)। मेरे पास टेम्पलेट की तरह ही सब कुछ सेट अप है।

हालांकि, मैं नमक जोड़ना चाहूंगा। मैं सृजन पर उपयोगकर्ता के लिए नमक उत्पन्न कर सकता हूं:

static func create(_ req: Request, newUserRequest user: CreateUserRequest) throws -> Future<User.Public> {
    return User.query(on: req).filter(\.username == user.username).first().flatMap { existingUser in
        guard existingUser == nil else {
            throw Abort(.badRequest, reason: "A user with the given username already exists.")
        }

        guard user.password == user.passwordVerification else {
            throw Abort(.badRequest, reason: "Given passwords did not match.")
        }

        let count = 16
        var pw_salt_data = Data(count: count)
        let _ = pw_salt_data.withUnsafeMutableBytes { mutableBytes in
            SecRandomCopyBytes(kSecRandomDefault, count, mutableBytes)
        }
        let pw_salt = try BCrypt.hash(pw_salt_data.base64EncodedString())

        let pw_hash = try BCrypt.hash(pw_salt + user.password)

        return User(id: nil, username: user.username, pw_hash: pw_hash, pw_salt: pw_salt, email: user.email).save(on: req).toPublic()
    }
}

लेकिन लॉगिन के दौरान प्रमाणीकरण करते समय उस नमक को पुनः प्राप्त करने का कोई तरीका नहीं है:

static func login(_ req: Request) throws -> Future<UserToken> {
    let user = try req.requireAuthenticated(User.self)
    let token = try UserToken.create(userID: user.requireID())
    return token.save(on: req)
}

मैं चाहता हूं कि नमक प्रत्येक उपयोगकर्ता के लिए यादृच्छिक रूप से उत्पन्न हो और बाद में प्रमाणीकरण के दौरान उपयोग किए जाने वाले हैश पासवर्ड से अलग कॉलम के रूप में डेटाबेस में संग्रहीत हो।

क्या वाष्प 3 में पासवर्ड हैश को नमकीन करने का एक मानकीकृत तरीका है?

3
Pierce Darragh 7 जिंदा 2019, 01:55

2 जवाब

सबसे बढ़िया उत्तर

जिस तरह से यह वाष्प में काम करता है वह यह है कि प्रत्येक BCrypt हैश में एक अद्वितीय नमक होता है जो डेटाबेस में पासवर्ड के साथ सहेजा जाता है। वाष्प में BCrypt डिफ़ॉल्ट फ़ंक्शन इसकी अपेक्षा करते हैं।

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

5
0xTim 7 जिंदा 2019, 21:46

आपने BCrypt का उपयोग करके पासवर्ड हैश कर लिया है। BCrypt पहले से ही वाष्प निर्भरता का हिस्सा है।

BCrypt.hash("vapor", cost: 4)

यह जटिलता के साथ, बेतरतीब ढंग से उत्पन्न नमक का उपयोग करते हुए स्ट्रिंग "वाष्प" को हैश करेगा। लागत का चयन व्यक्तिपरक और मनमाना है, लेकिन यह अनुशंसा की जाती है कि वास्तविक दुनिया के सुरक्षित अनुप्रयोगों में 10-12 से ऊपर का लागत कारक होना चाहिए। यदि आप BCrypt द्वारा बेतरतीब ढंग से उत्पन्न होने वाले नमक को पसंद नहीं करते हैं, और आप अपना स्वयं का नमक बनाना चाहते हैं, तो आप हैश फ़ंक्शन को नमक प्रदान कर सकते हैं, जिसमें निम्नलिखित हस्ताक्षर हैं:

public func hash(_ plaintext: LosslessDataConvertible, cost: Int = 12, salt: LosslessDataConvertible? = nil) throws -> String 

दस्तावेज़ीकरण कहता है कि यदि मैन्युअल रूप से प्रदान किया गया है तो नमक 16-बाइट्स का होना चाहिए। यह एक नमूना हैश है:

$2a$04$/nqhWqplnughhq6mlKmi8.raprxoG/dczY8kdbOKm.zC5sPu.2IBi

जैसा कि आप देख सकते हैं कि इसमें सहायक जानकारी जैसे कि जटिलता, एल्गोरिथम का प्रकार और नमक, सत्यापन करने के लिए आवश्यक सभी चीजें शामिल हैं। यदि आपने अपना स्वयं का नमक प्रदान किया है तो यह अंतिम हैश का भी हिस्सा होगा और आपको इसे अलग से प्रदान करने की आवश्यकता नहीं है। आप नीचे लिखे अनुसार सत्यापन कर सकते हैं।

try BCrypt.verify("vapor", created: hashedPasswordSavedInDatabase)
1
Gabriele 8 जिंदा 2019, 12:28