पाइथन में नमक और हैश का पासवर्ड


97

यह कोड एक नमक के साथ एक पासवर्ड हैश करने वाला है। डेटाबेस में नमक और हैशेड पासवर्ड को सहेजा जा रहा है। पासवर्ड ही नहीं है।

ऑपरेशन की संवेदनशील प्रकृति को देखते हुए, मैं यह सुनिश्चित करना चाहता था कि सब कुछ कोषेर था।

import hashlib
import base64
import uuid

password = 'test_password'
salt     = base64.urlsafe_b64encode(uuid.uuid4().bytes)


t_sha = hashlib.sha512()
t_sha.update(password+salt)
hashed_password =  base64.urlsafe_b64encode(t_sha.digest())

आप नमक क्यों कूट रहे हैं? यह सीधे नमक का उपयोग करने के लिए सरल होगा और फिर b64 दोनों को एक साथ सांकेतिक शब्दों में बदलना t_sha.digest() + salt। आप नमक को बाद में फिर से विभाजित कर सकते हैं जब आप नमकीन हैश पासवर्ड को डिकोड कर चुके होते हैं, जैसा कि आप जानते हैं कि डिकोडेड हैश पासवर्ड 32 बाइट्स है।
डंकन

1
@ डंकन - I बेस 64 ने नमक को कूट दिया ताकि मैं अजीब मुद्दों के बारे में चिंता किए बिना उस पर मजबूत संचालन कर सकूं। क्या "बाइट्स" संस्करण एक स्ट्रिंग के रूप में काम करेगा? यदि ऐसा है, तो मुझे t_sha.digest () या तो base64 एनकोड करने की आवश्यकता नहीं है। मैं शायद हैशेड पासवर्ड और नमक को एक साथ नहीं बचाऊंगा क्योंकि यह थोड़ा अधिक जटिल और थोड़ा कम पठनीय लगता है।
क्रिस डुट्रो

यदि आप पायथन 2.x का उपयोग कर रहे हैं तो बाइट ऑब्जेक्ट एक स्ट्रिंग के रूप में पूरी तरह से काम करेगा। अजगर एक स्ट्रिंग में आपके पास क्या हो सकता है पर कोई प्रतिबंध नहीं रखता है। हालाँकि, यदि आप स्ट्रिंग को किसी बाहरी कोड जैसे डेटाबेस से पास करते हैं तो यह लागू नहीं हो सकता है। पाइथन 3.x बाइट प्रकार और स्ट्रिंग्स को अलग करता है ताकि उस स्थिति में आप नमक पर स्ट्रिंग ऑपरेशन का उपयोग न करना चाहें।
डंकन

4
मैं आपको यह नहीं बता सकता कि इसे अजगर में कैसे करना है, लेकिन सादा SHA-512 एक बुरा विकल्प है। PBKDF2, bcrypt या scrypt जैसे धीमे हैश का उपयोग करें।
कोडइन्चेक

साइड नोट: मैं क्रिप्टोग्राफिक यादृच्छिकता के स्रोत के रूप में यूयूआईडी का उपयोग करने के खिलाफ सलाह दूंगा। हां, सीपीथॉन द्वारा उपयोग किया जाने वाला कार्यान्वयन क्रिप्टोग्राफिक रूप से सुरक्षित है , लेकिन यह पायथन की कल्पना और न ही यूयूआईडी युक्ति द्वारा निर्धारित नहीं है , और कमजोर कार्यान्वयन मौजूद है । यदि आपका कोडबेस सुरक्षित UUID4s के बिना पायथन कार्यान्वयन का उपयोग करके चला जाता है, तो आपने अपनी सुरक्षा को कमजोर कर दिया है। यह एक असंभावित परिदृश्य हो सकता है, लेकिन इसके secretsबदले उपयोग करने के लिए कुछ भी खर्च नहीं होता है ।
मार्क ऐमी

जवाबों:


49

EDIT: यह उत्तर गलत है। SHA512 का एक एकल पुनरावृत्ति तेज़ है , जो इसे पासवर्ड हैशिंग फ़ंक्शन के रूप में उपयोग करने के लिए अनुपयुक्त बनाता है। इसके बजाय अन्य उत्तरों में से किसी एक का उपयोग करें।


मेरे द्वारा ठीक लग रहा है। हालाँकि, मुझे पूरा यकीन है कि आपको वास्तव में बेस 64 की आवश्यकता नहीं है। आप ऐसा कर सकते हैं:

import hashlib, uuid
salt = uuid.uuid4().hex
hashed_password = hashlib.sha512(password + salt).hexdigest()

यदि यह कठिनाइयाँ पैदा नहीं करता है, तो आप अपने डेटाबेस में हेक्स स्ट्रिंग्स के बजाय कच्चे बाइट्स के रूप में नमक और हैशेड पासवर्ड स्टोर करके अपने डेटाबेस में थोड़ा और अधिक कुशल भंडारण प्राप्त कर सकते हैं। ऐसा करने के लिए, के hexसाथ bytesऔर hexdigestसाथ बदलें digest


1
हाँ, हेक्स ठीक काम करेगा। मैं बेस 64 को पसंद करता हूं क्योंकि स्ट्रिंग्स थोड़ी छोटी हैं। चारों ओर से गुजरने और छोटे तारों पर संचालन करने के लिए इसका अधिक कुशल है।
क्रिस डट्रो

अब, आप पासवर्ड वापस पाने के लिए इसे कैसे उल्टा करते हैं?
नोडबेस

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

4
uuid.uuid4 ()। हेक्स उत्पन्न होने पर हर बार अलग होता है। यदि आप समान यूयूआईडी वापस नहीं पा सकते हैं तो आप उद्देश्यों की जाँच के लिए पासवर्ड की तुलना कैसे करेंगे?
LittleBobbyTables

3
@LittleBobbyTables मुझे लगता saltहै कि डेटाबेस और नमकीन हैशेड पासवर्ड में भी संग्रहीत है।
क्लीमेटॉय

72

इस प्रश्न के अन्य उत्तरों के आधार पर, मैंने bcrypt का उपयोग करके एक नया दृष्टिकोण लागू किया है।

क्यों bcrypt का उपयोग करें

अगर मैं सही ढंग से समझ, तर्क का उपयोग करने के लिए bcryptखत्म हो गया SHA512है कि bcryptधीमी गति से होने के लिए बनाया गया है। bcryptपहली बार हैश पासवर्ड बनाते समय आप इसे कितना धीमा चाहते हैं, इसे समायोजित करने का विकल्प भी है:

# The '12' is the number that dictates the 'slowness'
bcrypt.hashpw(password, bcrypt.gensalt( 12 ))

धीमी गति से वांछनीय है क्योंकि यदि कोई दुर्भावनापूर्ण पार्टी हैशेड पासवर्ड वाली तालिका पर अपने हाथों को लेती है, तो उन्हें मजबूर करना अधिक कठिन होता है।

कार्यान्वयन

def get_hashed_password(plain_text_password):
    # Hash a password for the first time
    #   (Using bcrypt, the salt is saved into the hash itself)
    return bcrypt.hashpw(plain_text_password, bcrypt.gensalt())

def check_password(plain_text_password, hashed_password):
    # Check hashed password. Using bcrypt, the salt is saved into the hash itself
    return bcrypt.checkpw(plain_text_password, hashed_password)

टिप्पणियाँ

मैं पुस्तकालय का उपयोग कर एक लिनक्स सिस्टम में बहुत आसानी से स्थापित करने में सक्षम था:

pip install py-bcrypt

हालाँकि, मुझे अपने विंडोज़ सिस्टम पर इसे इंस्टॉल करने में अधिक परेशानी हुई। यह एक पैच की जरूरत प्रतीत होती है। इस स्टैक ओवरफ्लो प्रश्न को देखें: py-bcrypt को 7 7bit python से जीतना है


4
12, gensalt के लिए डिफ़ॉल्ट मान है
अहमद

2
Pypi.python.org/pypi/bcrypt/3.1.0 के अनुसार , bcrypt के लिए अधिकतम पासवर्ड की लंबाई 72 बाइट्स है। इससे आगे के किसी भी पात्र को अनदेखा किया जाता है। इस कारण से, वे पहले एक क्रिप्टोग्राफ़िक हैश फ़ंक्शन के साथ हैशिंग की अनुशंसा करते हैं और फिर हैश को आधार-एनकोड करते हैं (विवरण के लिए लिंक देखें)। पक्ष की टिप्पणी: ऐसा लगता py-bcryptहै कि यह पुराना पीपीआई पैकेज है और तब से इसका नाम बदल दिया गया है bcrypt
बालू

48

स्मार्ट चीज़ क्रिप्टो को स्वयं लिखना नहीं है, बल्कि पासलिब जैसी किसी चीज़ का उपयोग करना है: https://bitbucket.org/ecollins/passlib/wiki/Home

अपने क्रिप्टो कोड को सुरक्षित तरीके से लिखने में गड़बड़ करना आसान है। बुरी बात यह है कि गैर क्रिप्टो कोड के साथ आप अक्सर इसे तुरंत नोटिस करते हैं जब यह आपके प्रोग्राम के क्रैश होने के बाद से काम नहीं कर रहा होता है। जबकि क्रिप्टो कोड के साथ आपको अक्सर पता चलता है कि यह देर हो चुकी है और आपके डेटा से छेड़छाड़ की गई है। इसलिए मुझे लगता है कि किसी अन्य व्यक्ति द्वारा लिखे गए पैकेज का उपयोग करना बेहतर है, जो विषय के बारे में जानने योग्य है और जो कि युद्ध प्रोटोकॉल पर आधारित है।

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

इसके अलावा sha512 का सिर्फ एक दौर ही शब्दकोश हमलों के लिए अधिक संवेदनशील है। sha512 को तेजी से डिज़ाइन किया गया है और यह वास्तव में एक बुरी चीज है जब पासवर्ड को सुरक्षित रूप से संग्रहीत करने का प्रयास किया जाता है। अन्य लोगों ने इस सभी प्रकार के मुद्दों के बारे में लंबा और कठिन सोचा है ताकि आप बेहतर तरीके से इसका लाभ उठा सकें।


5
मुझे लगता है कि क्रायपो लाइब्रेरीज़ का उपयोग करने की सलाह अच्छी है, लेकिन ओपी पहले से ही हैशलीब का उपयोग कर रहा है, एक क्रिप्टो लाइब्रेरी जो पायथन स्टैंडर्ड लाइब्रेरी (पासलिब के विपरीत) में भी है। अगर मैं ओपी स्थिति में था, तो मैं हैशलीब का उपयोग करना जारी रखूंगा।
डेग

18
@dghubble hashlibक्रिप्टोग्राफिक हैश फ़ंक्शन के लिए है। passlibसुरक्षित रूप से पासवर्ड संग्रहीत करने के लिए है। वे एक ही बात नहीं कर रहे हैं (हालांकि बहुत से लोग ऐसा सोचते हैं .. और फिर उनके उपयोगकर्ताओं के पासवर्ड फट जाते हैं)।
ब्रेंडन लॉन्ग

3
यदि कोई सोच रहा है: passlibअपना स्वयं का नमक उत्पन्न करता है, जो लौटे हैश स्ट्रिंग में संग्रहीत होता है (कम से कम कुछ योजनाओं के लिए जैसे कि BCrypt + SHA256 ) - तो आपको इसके बारे में चिंता करने की आवश्यकता नहीं है।
zrr

22

पायथन 3 में काम करने के लिए आपको उदाहरण के लिए UTF-8 एनकोड करना होगा:

hashed_password = hashlib.sha512(password.encode('utf-8') + salt.encode('utf-8')).hexdigest()

अन्यथा आपको मिलेगा:

ट्रेसबैक (सबसे हालिया कॉल अंतिम):
फ़ाइल "", पंक्ति 1,
हैशेड_पासवर्ड में = hashlib.sha512 (पासवर्ड + नमक) .hexdigest () टाइपError
: यूनिकोड-ऑब्जेक्ट्स को हैशिंग से पहले एन्कोड किया जाना चाहिए।


7
नहीं। हैशिंग पासवर्ड के लिए किसी भी हैश फ़ंक्शन का उपयोग न करें। Bcrypt जैसी किसी चीज़ का उपयोग करें। कारण के लिए अन्य प्रश्नों के लिए टिप्पणी देखें।
शाम

13

पायथन 3.4 के रूप hashlibमें, मानक पुस्तकालय में मॉड्यूल में मुख्य व्युत्पत्ति कार्य हैं जो "सुरक्षित पासवर्ड हैशिंग" के लिए डिज़ाइन किए गए हैं

तो उन में से एक का उपयोग करें, जैसे hashlib.pbkdf2_hmac, एक नमक के उपयोग से उत्पन्न os.urandom:

from typing import Tuple
import os
import hashlib
import hmac

def hash_new_password(password: str) -> Tuple[bytes, bytes]:
    """
    Hash the provided password with a randomly-generated salt and return the
    salt and hash to store in the database.
    """
    salt = os.urandom(16)
    pw_hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
    return salt, pw_hash

def is_correct_password(salt: bytes, pw_hash: bytes, password: str) -> bool:
    """
    Given a previously-stored salt and hash, and a password provided by a user
    trying to log in, check whether the password is correct.
    """
    return hmac.compare_digest(
        pw_hash,
        hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
    )

# Example usage:
salt, pw_hash = hash_new_password('correct horse battery staple')
assert is_correct_password(salt, pw_hash, 'correct horse battery staple')
assert not is_correct_password(salt, pw_hash, 'Tr0ub4dor&3')
assert not is_correct_password(salt, pw_hash, 'rosebud')

ध्यान दें कि:

  • 16-बाइट नमक और PBKDF2 के 100000 पुनरावृत्तियों का उपयोग पायथन डॉक्स में अनुशंसित न्यूनतम संख्याओं से मेल खाता है। आगे पुनरावृत्तियों की संख्या बढ़ने से आपके हैश की गणना धीमी हो जाएगी, और इसलिए अधिक सुरक्षित।
  • os.urandom हमेशा यादृच्छिकता के एक गुप्त रूप से सुरक्षित स्रोत का उपयोग करता है
  • hmac.compare_digest, में प्रयोग किया जाता है is_correct_password, मूल रूप से ==स्ट्रिंग्स के लिए बस ऑपरेटर है, लेकिन शॉर्ट-सर्किट की क्षमता के बिना, जो इसे समय पर हमलों के लिए प्रतिरक्षा बनाता है। यही कारण है कि शायद वास्तव में किसी भी अतिरिक्त सुरक्षा मूल्य प्रदान नहीं करता है , लेकिन यह चोट नहीं करता है, या तो इसलिए मैं अगला कदम उठाते हुए यह प्रयोग किया है।

क्या एक अच्छा पासवर्ड हैश के लिए सिद्धांत और साथ में हैशिंग पासवर्ड के लिए उपयुक्त अन्य कार्यों की एक सूची बनाता है, https://security.stackexchange.com/q/211/29805 देखें


11

यदि आपको किसी मौजूदा सिस्टम द्वारा संग्रहीत हैश का उपयोग करने की आवश्यकता है, तो पासलिब उपयोगी प्रतीत होता है। यदि आपके पास प्रारूप का नियंत्रण है, तो bcrypt या scrypt जैसे आधुनिक हैश का उपयोग करें। इस समय, अजगर से अजगर का उपयोग करना बहुत आसान लगता है।

पासलिब bcrypt का समर्थन करता है, और यह बैकएंड के रूप में py-bcrypt को स्थापित करने की सिफारिश करता है: http://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html

यदि आप पासलिब स्थापित नहीं करना चाहते हैं तो आप सीधे py-bcrypt का उपयोग कर सकते हैं । रीडमी के मूल उपयोग के उदाहरण हैं।

यह भी देखें: पायथन में पासवर्ड और नमक के लिए हैश उत्पन्न करने के लिए स्क्रीप्ट का उपयोग कैसे करें


6

मैं डॉन 'एक पुराने धागे को फिर से जीवित करना चाहता हूं, लेकिन ... जो कोई भी आधुनिक समाधान का उपयोग करना चाहता है, वह आर्गन 2 का उपयोग कर सकता है।

https://pypi.python.org/pypi/argon2_cffi

इसने पासवर्ड हैशिंग प्रतियोगिता जीती। ( https://password-hashing.net/ ) यह bcrypt की तुलना में उपयोग करना आसान है, और यह bcrypt की तुलना में अधिक सुरक्षित है।


0

सबसे पहले आयात: -

import hashlib, uuid

फिर अपनी विधि के अनुसार अपना कोड बदलें:

uname = request.form["uname"]
pwd=request.form["pwd"]
salt = hashlib.md5(pwd.encode())

फिर इस नमक को अपने डेटाबेस sql क्वेरी में पास करें और लॉगिन करें, नीचे लॉगिन एक टेबल का नाम है:

sql = "insert into login values ('"+uname+"','"+email+"','"+salt.hexdigest()+"')"

uname = request.form ["uname"] pwd = request.form ["pwd"] नमक = hashlib.md5 (pwd.encode ()) फिर इस नमक को पास करें और अपने डेटाबेस sql क्वेरी में uname, नीचे लॉगिन एक टेबल का नाम है : - sql = "लॉगिन मानों में प्रविष्ट करें ('' + + uname +" ',' '+ ईमेल +' ',' '+ salt.hexdigest () + "')"
शीतल झा

-1 क्योंकि md5 बहुत तेज़ है, जो md5 के एकल पुनरावृत्ति का उपयोग करके पासवर्ड हैशिंग फ़ंक्शन के लिए एक खराब विकल्प बनाता है।
मार्क अमेरी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.