Programing

파이썬에서 소금과 해시 암호

lottogame 2020. 10. 21. 07:38
반응형

파이썬에서 소금과 해시 암호


이 코드는 솔트를 사용하여 암호를 해시해야합니다. 솔트 및 해시 된 암호가 데이터베이스에 저장됩니다. 암호 자체는 아닙니다.

수술의 민감한 특성을 감안할 때 모든 것이 정결한지 확인하고 싶었습니다.

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

편집 : 이 대답은 잘못되었습니다. SHA512의 단일 반복은 빠르기 때문에 암호 해싱 기능으로 사용하기에 부적절합니다. 대신 여기에 다른 답변 중 하나를 사용하십시오.


내가보기에 괜찮아 보인다. 그러나 실제로 base64가 필요하지 않다고 확신합니다. 다음과 같이 할 수 있습니다.

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

문제가 발생하지 않는 경우 솔트 및 해시 된 암호를 16 진수 문자열이 아닌 원시 바이트로 저장하여 데이터베이스에 약간 더 효율적인 저장소를 얻을 수 있습니다. 이렇게하려면, 교체 hexbyteshexdigest함께 digest.


이 질문에 대한 다른 답변을 바탕으로 bcrypt를 사용하여 새로운 접근 방식을 구현했습니다.

bcrypt를 사용하는 이유

내가 올바르게 이해한다면 bcryptover 사용에 대한 주장 은 느리게 설계 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)

메모

다음을 사용하여 Linux 시스템에서 라이브러리를 매우 쉽게 설치할 수있었습니다.

pip install py-bcrypt

그러나 Windows 시스템에 설치하는 데 더 많은 문제가있었습니다. 패치가 필요한 것 같습니다. 이 스택 오버플로 질문을 참조하십시오 : Win 7 64bit Python에 설치하는 py-bcrypt


현명한 것은 암호를 직접 작성하는 것이 아니라 passlib와 같은 것을 사용하는 것입니다 : https://bitbucket.org/ecollins/passlib/wiki/Home

안전한 방법으로 암호화 코드를 작성하는 것은 엉망이되기 쉽습니다. 불쾌한 점은 암호화가 아닌 코드를 사용하면 프로그램이 충돌하기 때문에 작동하지 않을 때 즉시 알아 차릴 수 있다는 것입니다. 암호화 코드를 사용하면 늦게까지 데이터가 손상된 후에 만 ​​알 수 있습니다. 따라서 주제에 대해 잘 알고 있고 전투 테스트 프로토콜을 기반으로하는 다른 사람이 작성한 패키지를 사용하는 것이 더 낫다고 생각합니다.

또한 passlib에는 사용하기 쉽고 오래된 프로토콜이 깨졌을 때 새로운 암호 해싱 프로토콜로 쉽게 업그레이드 할 수있는 몇 가지 멋진 기능이 있습니다.

또한 단일 라운드의 sha512는 사전 공격에 더 취약합니다. sha512는 빠르도록 설계되었으며 이것은 실제로 암호를 안전하게 저장하려고 할 때 나쁜 일입니다. 다른 사람들은이 모든 종류의 문제에 대해 오랫동안 열심히 생각했기 때문에 이것을 더 잘 활용할 수 있습니다.


이 작업이 Python 3에서 작동하려면 다음과 같이 UTF-8 인코딩이 필요합니다.

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

그렇지 않으면 다음을 얻을 수 있습니다.

역 추적 (가장 최근 호출 마지막) :
파일 "", 줄 1, in
hashed_password = hashlib.sha512 (password + salt) .hexdigest ()
TypeError : Unicode-objects must be encoding before hashing


passlib는 기존 시스템에 저장된 해시를 사용해야하는 경우 유용합니다. 형식을 제어 할 수있는 경우 bcrypt 또는 scrypt와 같은 최신 해시를 사용하십시오. 현재, bcrypt는 파이썬에서 사용하기 훨씬 더 쉬운 것 같습니다.

passlib는 bcrypt를 지원하며 py-bcrypt를 백엔드로 설치할 것을 권장합니다 : http://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html

passlib 를 설치하지 않으려면 py-bcrypt를 직접 사용할 수도 있습니다 . Readme에는 기본 사용 예제가 있습니다.

참조 : scrypt를 사용하여 Python에서 비밀번호 및 솔트에 대한 해시를 생성하는 방법


오래된 스레드를 부활시키고 싶지는 않지만 ... 최신 보안 솔루션을 사용하려는 사람은 누구나 argon2를 사용하십시오.

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

암호 해싱 대회에서 우승했습니다. ( https://password-hashing.net/ ) bcrypt보다 사용하기 쉽고 bcrypt보다 안전합니다.


Python 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 회 반복은 Python 문서에서 권장하는 최소 숫자와 일치합니다. 반복 횟수를 더 늘리면 해시 계산 속도가 느려지므로 더 안전합니다.
  • os.urandom 항상 암호 학적으로 안전한 무작위 소스를 사용합니다.
  • hmac.compare_digest, used in is_correct_password, is basically just the == operator for strings but without the ability to short-circuit, which makes it immune to timing attacks. That probably doesn't really provide any extra security value, but it doesn't hurt, either, so I've gone ahead and used it.

For theory on what makes a good password hash and a list of other functions appropriate for hashing passwords with, see https://security.stackexchange.com/q/211/29805.


Firstly import:-

import hashlib, uuid

Then change your code according to this in your method:

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

Then pass this salt and uname in your database sql query, below login is a table name:

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

참고URL : https://stackoverflow.com/questions/9594125/salt-and-hash-a-password-in-python

반응형