Kode ini seharusnya hash kata sandi dengan garam. Kata sandi salt dan hash sedang disimpan dalam database. Kata sandi itu sendiri tidak.
Mengingat sifat sensitif dari operasi tersebut, saya ingin memastikan semuanya halal.
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())
t_sha.digest() + salt
. Anda dapat membagi salt lagi nanti ketika Anda telah memecahkan kode kata sandi hash yang diasinkan karena Anda tahu kata sandi hash yang didekodekan persis 32 byte.secrets
sebagai gantinya.Jawaban:
EDIT: Jawaban ini salah. Sebuah iterasi tunggal SHA512 cepat , yang membuatnya tidak sesuai untuk digunakan sebagai fungsi hashing kata sandi. Gunakan salah satu jawaban lain di sini.
Tampak baik-baik saja oleh saya. Namun, saya cukup yakin Anda tidak benar-benar membutuhkan base64. Anda bisa melakukan ini:
import hashlib, uuid salt = uuid.uuid4().hex hashed_password = hashlib.sha512(password + salt).hexdigest()
Jika tidak menimbulkan kesulitan, Anda bisa mendapatkan penyimpanan yang sedikit lebih efisien dalam database Anda dengan menyimpan kata sandi salt dan hash sebagai byte mentah daripada string hex. Untuk melakukannya, ganti
hex
denganbytes
danhexdigest
dengandigest
.sumber
salt
disimpan dalam database dan kata sandi hash asin juga.Berdasarkan jawaban lain untuk pertanyaan ini, saya telah menerapkan pendekatan baru menggunakan bcrypt.
Mengapa menggunakan bcrypt
Jika saya mengerti benar, argumen untuk menggunakan
bcrypt
lebihSHA512
adalah bahwabcrypt
dirancang untuk menjadi lambat.bcrypt
juga memiliki opsi untuk menyesuaikan seberapa lambat Anda menginginkannya saat membuat kata sandi berciri untuk pertama kalinya:# The '12' is the number that dictates the 'slowness' bcrypt.hashpw(password, bcrypt.gensalt( 12 ))
Lambat diinginkan karena jika pihak jahat mendapatkan tangan mereka di atas meja yang berisi kata sandi hash, maka jauh lebih sulit untuk memaksa mereka.
Penerapan
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)
Catatan
Saya dapat menginstal pustaka dengan cukup mudah di sistem linux menggunakan:
Namun, saya mengalami lebih banyak masalah saat menginstalnya di sistem windows saya. Tampaknya membutuhkan tambalan. Lihat pertanyaan Stack Overflow ini: py-bcrypt menginstal pada win 7 64bit python
sumber
py-bcrypt
paket pypi lama dan sejak itu diubah namanya menjadibcrypt
.Hal yang cerdas bukanlah menulis kripto sendiri tetapi menggunakan sesuatu seperti passlib: https://bitbucket.org/ecollins/passlib/wiki/Home
Sangat mudah untuk mengacaukan penulisan kode kripto Anda dengan cara yang aman. Hal yang buruk adalah bahwa dengan kode non crypto Anda sering segera menyadarinya ketika tidak berfungsi karena program Anda macet. Sementara dengan kode kripto Anda sering hanya mengetahuinya setelah terlambat dan data Anda telah dikompromikan. Oleh karena itu saya pikir lebih baik menggunakan paket yang ditulis oleh orang lain yang memiliki pengetahuan tentang subjek dan yang didasarkan pada protokol yang diuji pertempuran.
Passlib juga memiliki beberapa fitur bagus yang membuatnya mudah digunakan dan juga mudah untuk ditingkatkan ke protokol hashing kata sandi yang lebih baru jika protokol lama ternyata rusak.
Juga hanya satu putaran sha512 yang lebih rentan terhadap serangan kamus. sha512 dirancang untuk menjadi cepat dan ini sebenarnya hal yang buruk ketika mencoba menyimpan kata sandi dengan aman. Orang lain telah berpikir panjang dan keras tentang semua masalah semacam ini sehingga Anda sebaiknya memanfaatkan ini.
sumber
hashlib
adalah untuk fungsi hash kriptografi.passlib
adalah untuk menyimpan sandi dengan aman. Mereka bukanlah hal yang sama (meskipun banyak orang tampaknya berpikir demikian .. dan kemudian kata sandi pengguna mereka dibobol).passlib
menghasilkan garamnya sendiri, yang disimpan dalam string hash yang dikembalikan (setidaknya untuk skema tertentu seperti BCrypt + SHA256 ) - jadi Anda tidak perlu mengkhawatirkannya.Agar ini berfungsi dengan Python 3, Anda harus menyandikan UTF-8 misalnya:
hashed_password = hashlib.sha512(password.encode('utf-8') + salt.encode('utf-8')).hexdigest()
Jika tidak, Anda akan mendapatkan:
sumber
Pada Python 3.4,
hashlib
modul di pustaka standar berisi fungsi derivasi kunci yang "dirancang untuk hashing sandi yang aman" .Jadi gunakan salah satu dari itu, seperti
hashlib.pbkdf2_hmac
, dengan garam yang dihasilkan menggunakanos.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')
Perhatikan bahwa:
os.urandom
selalu menggunakan sumber keacakan yang aman secara kriptografishmac.compare_digest
, digunakan dalamis_correct_password
, pada dasarnya hanyalah==
operator untuk string tetapi tanpa kemampuan untuk hubungan pendek, yang membuatnya kebal terhadap serangan waktu. Itu mungkin tidak benar-benar memberikan nilai keamanan tambahan , tetapi tidak ada salahnya, jadi saya telah melanjutkan dan menggunakannya.Untuk teori tentang apa yang membuat hash kata sandi yang baik dan daftar fungsi lain yang sesuai untuk hash kata sandi dengan, lihat https://security.stackexchange.com/q/211/29805 .
sumber
passlib tampaknya berguna jika Anda perlu menggunakan hash yang disimpan oleh sistem yang ada. Jika Anda memiliki kendali atas formatnya, gunakan hash modern seperti bcrypt atau scrypt. Saat ini, bcrypt tampaknya lebih mudah digunakan dari python.
passlib mendukung bcrypt, dan merekomendasikan menginstal py-bcrypt sebagai backend: http://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html
Anda juga dapat menggunakan py-bcrypt secara langsung jika Anda tidak ingin menginstal passlib. Readme memiliki contoh penggunaan dasar.
lihat juga: Cara menggunakan scrypt untuk menghasilkan hash untuk kata sandi dan garam dengan Python
sumber
Saya tidak ingin menghidupkan kembali utas lama, tetapi ... siapa pun yang ingin menggunakan solusi aman terkini, gunakan argon2.
https://pypi.python.org/pypi/argon2_cffi
Itu memenangkan kompetisi hashing kata sandi. ( https://password-hashing.net/ ) Lebih mudah digunakan daripada bcrypt, dan lebih aman daripada bcrypt.
sumber
Impor pertama: -
import hashlib, uuid
Kemudian ubah kode Anda sesuai dengan ini di metode Anda:
uname = request.form["uname"] pwd=request.form["pwd"] salt = hashlib.md5(pwd.encode())
Kemudian berikan salt dan uname ini dalam kueri sql database Anda, di bawah ini login adalah nama tabel:
sql = "insert into login values ('"+uname+"','"+email+"','"+salt.hexdigest()+"')"
sumber