পাইথনে লবণ এবং হ্যাশ একটি পাসওয়ার্ড


93

এই কোডটিতে লবণের সাথে একটি পাসওয়ার্ড হ্যাশ করার কথা। লবণ এবং হ্যাশ পাসওয়ার্ড ডাটাবেসে সংরক্ষণ করা হচ্ছে। পাসওয়ার্ড নিজেই হয় না।

অপারেশনের সংবেদনশীল প্রকৃতির প্রবণতা দেখে আমি নিশ্চিত করতে চেয়েছিলাম যে সমস্ত কিছু কোশার ছিল।

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())

আপনি বি 64 কেন লবণের এনকোডিং করছেন? সরাসরি লবণ সরাসরি ব্যবহার করা সহজ হবে এবং তারপরে বি 64 উভয়কে একসাথে এনকোড করা সহজ হবে t_sha.digest() + salt। আপনি লবণযুক্ত হ্যাশ পাসওয়ার্ডটি ডিকোড করার পরে লবণটি আবার বিভক্ত করতে পারেন কারণ আপনি জানেন যে ডিকোডড হ্যাশ পাসওয়ার্ডটি হুবহু 32 বাইট।
ডানকান

4
@ ডানকান - আমি বেসট 64 কে লবণটি এনকোড করেছি যাতে আমি অদ্ভুত সমস্যা নিয়ে চিন্তা না করেই এর উপর দৃ strong় অপারেশন করতে পারি। "বাইটস" সংস্করণটি কি স্ট্রিং হিসাবে কাজ করবে? যদি এটি হয় তবে আমার আর t_sha.digest () এর এনকোড বেস 64 করতে হবে না। আমি সম্ভবত হ্যাশ পাসওয়ার্ড এবং লবণ একসাথে সংরক্ষণ করতে পারব না কারণ এটি আরও জটিল এবং কিছুটা কম পঠনযোগ্য বলে মনে হচ্ছে।
ক্রিস ডাট্রো

আপনি যদি পাইথন ২.x ব্যবহার করছেন তবে বাইটস অবজেক্ট স্ট্রিংয়ের মতো পুরোপুরি কাজ করবে। পাইথন আপনার কাছে স্ট্রিংয়ে থাকতে পারে এমন কোনও বিধিনিষেধ দেয় না। তবে আপনি যদি কোনও ডাটাবেসের মতো কোনও বাহ্যিক কোডে স্ট্রিংটি পাস করেন তবে একই জিনিস প্রয়োগ নাও হতে পারে। পাইথন x.x বাইট প্রকার এবং স্ট্রিংগুলিকে আলাদা করে দেয় সে ক্ষেত্রে আপনি লবণের উপর স্ট্রিং ক্রিয়াকলাপগুলি ব্যবহার করতে চাইবেন না।
ডানকান

4
অজগরে এটি কীভাবে করবেন তা আমি আপনাকে বলতে পারি না, তবে সরল SHA-512 একটি খারাপ পছন্দ। PBKDF2, bcrypt বা scrypt এর মতো ধীর গতির হ্যাশ ব্যবহার করুন।
কোডসইনচায়োস

পার্শ্ব নোট: আমি ক্রিপ্টোগ্রাফিক এলোমেলোতার উত্স হিসাবে ইউআইডি ব্যবহার করার বিরুদ্ধে পরামর্শ দেব। হ্যাঁ, সিপিথন দ্বারা ব্যবহৃত বাস্তবায়ন ক্রিপ্টোগ্রাফিকভাবে নিরাপদ , তবে এটি পাইথনের স্পেক বা ইউইউডি স্পেক দ্বারা নির্ধারিত নয় এবং দুর্বল বাস্তবায়নগুলি বিদ্যমান । যদি আপনার কোডবেস সুরক্ষিত ইউইউডি 4 গুলি ছাড়াই পাইথন বাস্তবায়ন ব্যবহার করে চলে যায় তবে আপনি আপনার সুরক্ষা দুর্বল করে ফেলবেন। এটি একটি অপ্রত্যাশিত দৃশ্য হতে পারে, তবে এর secretsপরিবর্তে এটি ব্যবহার করার জন্য কিছুই ব্যয় করে না ।
মার্ক

উত্তর:


49

সম্পাদনা: এই উত্তরটি ভুল। SHA512 এর একক পুনরাবৃত্তি দ্রুত , যা এটি পাসওয়ার্ড হ্যাশিং ফাংশন হিসাবে ব্যবহারের জন্য অনুপযুক্ত করে তোলে। পরিবর্তে এখানে অন্য একটি উত্তর ব্যবহার করুন।


আমার ভাল লাগছে। তবে আমি নিশ্চিত যে আপনার আসলে বেস 64 এর দরকার নেই। আপনি কেবল এটি করতে পারেন:

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

যদি এটি অসুবিধা না সৃষ্টি করে তবে আপনি হেক্স স্ট্রিংয়ের পরিবর্তে কাঁচা বাইট হিসাবে লবণ এবং হ্যাশ পাসওয়ার্ড সংরক্ষণ করে আপনার ডেটাবেজে কিছুটা দক্ষ স্টোরেজ পেতে পারেন। এটি করার জন্য, hexসাথে bytesএবং hexdigestসাথে প্রতিস্থাপন করুন digest


4
হ্যাঁ, হেক্স ঠিক কাজ করবে। আমি বেস 64 পছন্দ করি কারণ স্ট্রিংগুলি আরও ছোট হয়। সংক্ষিপ্ত স্ট্রিংগুলিতে কাজ করা এবং পরিচালনা করা এর আরও দক্ষ more
ক্রিস ডাট্রো

এখন, পাসওয়ার্ডটি ফিরে পেতে আপনি কীভাবে এটি বিপরীত করবেন?
নোডবেস

28
আপনি এটি বিপরীত করবেন না, আপনি কখনই কোনও পাসওয়ার্ড বিপরীত করবেন না। এজন্য আমরা এটি হ্যাশ করি এবং আমরা এটি এনক্রিপ্ট করি না। আপনার যদি কোনও সঞ্চিত পাসওয়ার্ডের সাথে কোনও ইনপুট পাসওয়ার্ডের তুলনা করতে হয় তবে আপনি ইনপুটটি হ্যাশ করে এবং হ্যাশগুলির সাথে তুলনা করুন। আপনি যদি কোনও পাসওয়ার্ড এনক্রিপ্ট করেন তবে কী সহ যে কেউ এটিকে ডিক্রিপ্ট করে এটি দেখতে পারেন। এটি নিরাপদ নয়
সেবাস্তিয়ান গ্যাব্রিয়েল ভিঞ্চি

4
uuid.uuid4 ()। হেক্স প্রতিটি সময় উত্পন্ন হওয়ার সময় আলাদা হয়। আপনি যদি একই ইউউইডটি ফিরে না পান তবে পরীক্ষার উদ্দেশ্যে আপনি কীভাবে একটি পাসওয়ার্ডের তুলনা করতে যাচ্ছেন?
লিটলববিটাইবলস

4
@ লিটলববি টেবিলগুলি আমার মনে saltহয় ডেটাবেজে এবং লবণের হ্যাশ পাসওয়ার্ডেও সংরক্ষণ করা আছে।
ক্লিমেটয়ে

70

এই প্রশ্নের অন্যান্য উত্তরের উপর ভিত্তি করে, আমি 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

তবে আমার উইন্ডোজ সিস্টেমে এটি ইনস্টল করতে আমার আরও সমস্যা হয়েছিল। এটি একটি প্যাচ প্রয়োজন বলে মনে হচ্ছে। এই স্ট্যাক ওভারফ্লো প্রশ্নটি দেখুন: উইন 7 64 বিট পাইথন ইনস্টল করে পাই-বিক্রিপ্ট


4
জেনসাল্টের জন্য 12 ডিফল্ট মান
আহমেদ

4
Pypi.python.org/pypi/bcrypt/3.1.0 অনুসারে , bcrypt এর সর্বাধিক পাসওয়ার্ডের দৈর্ঘ্য 72 বাইট। এর বাইরে যে কোনও অক্ষর উপেক্ষা করা হবে। এই কারণে, তারা প্রথমে একটি ক্রিপ্টোগ্রাফিক হ্যাশ ফাংশন দিয়ে হ্যাশ করার পরামর্শ দেয় এবং তারপরে হ্যাশটি বেস 64-এনকোড করতে (বিশদটির জন্য লিঙ্কটি দেখুন)। পার্শ্ব মন্তব্য: মনে py-bcryptহচ্ছে এটি পুরানো পাইপাই প্যাকেজ এবং এর পরে নামকরণ করা হয়েছে bcrypt
বালু

48

স্মার্ট জিনিসটি হ'ল নিজে ক্রিপ্টো লেখার জন্য নয় বরং পাসলিবের মতো কিছু ব্যবহার করার জন্য: https://bitbucket.org/ecollins/passlib/wiki/Home

আপনার ক্রিপ্টো কোডটি সুরক্ষিত উপায়ে লিখে ফেলতে সহজ। বাজে জিনিসটি হ'ল নন ক্রিপ্টো কোড সহ আপনি যখনই আপনার প্রোগ্রামটি ক্র্যাশ হয়ে যাচ্ছেন তখন এটি কাজ না করে আপনি প্রায়শই তাৎক্ষণিকভাবে তা লক্ষ্য করেন। ক্রিপ্টো কোড সহ আপনি প্রায়ই এটি কেবল দেরি হওয়ার পরে খুঁজে পান এবং আপনার ডেটা আপোস করা হওয়ার পরে। এর জন্য আমি মনে করি যে এই বিষয় সম্পর্কে জ্ঞাতযোগ্য এবং যুদ্ধ পরীক্ষিত প্রোটোকলের উপর ভিত্তি করে অন্য কারও দ্বারা লিখিত প্যাকেজ ব্যবহার করা ভাল।

পাসলিবিতে কিছু দুর্দান্ত বৈশিষ্ট্য রয়েছে যা পুরানো প্রোটোকলটি ভেঙে বেরিয়ে আসে যদি নতুন পাসওয়ার্ড হ্যাশিং প্রোটোকলটি এটি ব্যবহার করা সহজ করে তোলে এবং আপগ্রেড করাও সহজ করে তোলে।

এছাড়াও sha512 এর একটি মাত্র রাউন্ড অভিধান আক্রমণে বেশি ঝুঁকিপূর্ণ। sha512 দ্রুত হওয়ার জন্য ডিজাইন করা হয়েছে এবং পাসওয়ার্ডগুলি নিরাপদে সংরক্ষণের চেষ্টা করার সময় এটি আসলে একটি খারাপ জিনিস। অন্যান্য ব্যক্তিরা এই ধরণের সমস্ত সমস্যা সম্পর্কে দীর্ঘ এবং কঠোর চিন্তা করেছে তাই আপনি আরও ভালভাবে এটির সুবিধা নিন।


4
আমি মনে করি ক্রিপো লাইব্রেরি ব্যবহারের পরামর্শটি ভাল, তবে ওপি ইতিমধ্যে হ্যাশলিব ব্যবহার করছে, এটি একটি ক্রিপ্টো লাইব্রেরি যা পাইথন স্ট্যান্ডার্ড লাইব্রেরিতেও রয়েছে (পাসলিবের বিপরীতে)। আমি যদি ওপিএস পরিস্থিতিতে থাকতাম তবে আমি হ্যাশলিব ব্যবহার চালিয়ে যাব।
12

18
@ ডিঘবাল hashlibক্রিপ্টোগ্রাফিক হ্যাশ ফাংশনগুলির জন্য for passlibনিরাপদে পাসওয়ার্ড সংরক্ষণের জন্য। এগুলি একই জিনিস নয় (যদিও অনেক লোক মনে হয় এমনটি মনে হয় .. এবং তারপরে তাদের ব্যবহারকারীর পাসওয়ার্ড ক্র্যাক হয়ে যায়)।
ব্রেন্ডন লং

4
যদি কেউ ভাবছেন: passlibতার নিজস্ব লবণ তৈরি করে, যা প্রত্যাবর্তিত হ্যাশ স্ট্রিংয়ে অন্তত সঞ্চিত হয় (কমপক্ষে বিসিক্রিপ্ট + এসএএএল 256 এর মতো নির্দিষ্ট স্কিমগুলির জন্য ) - সুতরাং আপনাকে এটি নিয়ে চিন্তা করার দরকার নেই।
z0r

22

পাইথন 3 এ কাজ করার জন্য আপনাকে ইউটিএফ -8 এনকোড লাগাতে হবে:

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

অন্যথায় আপনি পাবেন:

ট্রেসব্যাক ( সর্বশেষতম কল শেষ):
ফাইল "", লাইন 1,
হ্যাশডপ্যাসওয়ার্ডে = hashlib.sha512 (পাসওয়ার্ড + লবন) .হেক্সডিজাস্ট () প্রকারের ত্রুটি
: হ্যাশিংয়ের আগে ইউনিকোড-অবজেক্টগুলি এনকোড করতে হবে


7
পাসওয়ার্ডগুলি হ্যাশ করার জন্য কোনও শ হ্যাশ ফাংশন ব্যবহার করবেন না। বিক্রিপ্টের মতো কিছু ব্যবহার করুন। কারণে অন্যান্য প্রশ্নের মন্তব্য দেখুন।
জোশ

11

পাইথন ৩.৪ অনুসারে, 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')

মনে রাখবেন যে:

  • পিবিকেডিএফ 2 এর 16-বাইট লবণ এবং 100000 পুনরাবৃত্তির ব্যবহার পাইথন ডক্সে প্রস্তাবিত সর্বনিম্ন সংখ্যার সাথে মেলে। পুনরাবৃত্তির সংখ্যা আরও বৃদ্ধি করা আপনার হ্যাশগুলি গণনা করতে ধীর করে দেবে এবং এর ফলে আরও সুরক্ষিত হবে।
  • os.urandom সর্বদা এলোমেলোতার একটি ক্রিপ্টোগ্রাফিক নিরাপদ উত্স ব্যবহার করে
  • hmac.compare_digestব্যবহৃত is_correct_password, এটি মূলত কেবল ==স্ট্রিংগুলির জন্য অপারেটর তবে শর্ট সার্কিটের ক্ষমতা ছাড়াই, যা এটি টাইমিং আক্রমণে প্রতিরোধক করে তোলে। এটি সম্ভবত কোনও অতিরিক্ত সুরক্ষা মান সরবরাহ করে না তবে এটির কোনও ক্ষতি হয় না, তাই আমি এগিয়ে গিয়ে ব্যবহার করেছি।

কী কারণে একটি ভাল পাসওয়ার্ড হ্যাশ তৈরি হয় এবং অন্যান্য পাসওয়ার্ডগুলির সাথে পাসওয়ার্ডগুলি হ্যাশ করার জন্য উপযুক্ত অন্যান্য কার্যগুলির তালিকা তৈরি করার তত্ত্বের জন্য, https://security.stackexchange.com/q/211/29805 দেখুন


10

Passlib দরকারী মনে হয় যদি আপনার কোনও বিদ্যমান সিস্টেমের দ্বারা সঞ্চিত হ্যাশগুলি ব্যবহার করার প্রয়োজন হয়। আপনার যদি ফর্ম্যাটের নিয়ন্ত্রণ থাকে তবে একটি আধুনিক হ্যাশ ব্যবহার করুন যেমন ব্রিসিপ বা স্ক্রিপ্ট। এই মুহুর্তে, অজগর থেকে বিক্রিপ্ট ব্যবহার করা অনেক সহজ বলে মনে হচ্ছে।

পাসলিব bcrypt সমর্থন করে এবং এটি পি-বিক্রিপটকে ব্যাকএন্ড হিসাবে ইনস্টল করার পরামর্শ দেয়: http://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html

এছাড়াও আপনি ব্যবহার করতে পারে PY-bcrypt আপনি passlib ইনস্টল করতে না চান সরাসরি। রিডমেতে বেসিক ব্যবহারের উদাহরণ রয়েছে।

আরও দেখুন: পাইথনে পাসওয়ার্ড এবং লবণের জন্য হ্যাশ উত্পন্ন করতে স্ক্রিপ্টটি কীভাবে ব্যবহার করবেন


6

আমি কোনও পুরানো থ্রেডটি পুনরুত্থিত করতে চাই না, তবে ... যে কেউ আধুনিক আপ টু ডেট সুরক্ষিত সমাধান ব্যবহার করতে চায়, তিনি আর্গন 2 ব্যবহার করুন।

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

এটি পাসওয়ার্ড হ্যাশিং প্রতিযোগিতা জিতেছে। ( https://password-hashing.net/ ) বিসিক্রিপ্টের চেয়ে এটি ব্যবহার করা সহজ, এবং এটি বিক্রিপ্টের চেয়ে বেশি সুরক্ষিত।


0

প্রথমত আমদানি করুন: -

import hashlib, uuid

তারপরে আপনার পদ্ধতিতে এটি অনুসারে আপনার কোডটি পরিবর্তন করুন:

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

তারপরে এই লবণটি পাস করুন এবং আপনার ডাটাবেস স্ক্যাল ক্যোয়ারিতে অবিচ্ছিন্ন করুন, নীচে লগইনটির একটি সারণির নাম রয়েছে:

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

uname = विनंती.for ["uname"] pwd = विनंती.for ["pwd"] লবণ = hashlib.md5 (pwd.encode ()) তারপরে এই লবণটি এবং আপনার পরিচয় ডাটাবেস sql ক্যোয়ারিতে uname দিন, নীচে লগইন একটি সারণির নাম : - sql = "লগইন মানগুলিতে'োকান ('" + আনমেম + "', '" + ইমেল + "', '" লবণ.হেক্সডিজাস্ট () + "')"
শীতল ঝা

-1 কারণ এমডি 5 খুব দ্রুত, যা এমডি 5 এর একক পুনরাবৃত্তি ব্যবহার করে একটি পাসওয়ার্ড হ্যাশিং ফাংশনের জন্য দুর্বল পছন্দ করে।
মার্ক আমেরিকা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.