programing

Python의 salt and hash 암호

subpage 2023. 9. 11. 21:49
반응형

Python의 salt and hash 암호

이 코드는 솔트로 암호를 해시해야 합니다.salt 및 hash 암호가 데이터베이스에 저장되고 있습니다.암호 자체는 그렇지 않습니다.

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

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

이 질문에 대한 다른 답변을 바탕으로 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 on win 7 64bit python

편집: 이 대답은 틀렸습니다.SHA512의 단일 반복은 빠르기 때문에 암호 해싱 기능으로 사용하기에 적합하지 않습니다.대신 여기에 다른 답변 중 하나를 사용합니다.


제가 보기엔 괜찮은 것 같네요.하지만 64번 베이스는 필요 없으실 거라고 확신합니다.그냥 이렇게 할 수도 있어요.

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

문제가 발생하지 않는 경우 salt 및 hash 암호를 16진수 문자열이 아닌 원시 바이트로 저장하여 데이터베이스에 약간 더 효율적인 스토리지를 확보할 수 있습니다.바꾸려면 를 바꿉니다.hex와 함께bytes그리고.hexdigest와 함께digest.

편집:

이 답변에서 제안한 라이브러리는 이제 구식이며, 이 답변에서 언급한 해시립유도 기능: https://stackoverflow.com/a/56915300/893857 은 요즘 사용하기 좋은 제안입니다.

독창적인 답 현명한 것은 암호를 직접 쓰는 것이 아니라 패스립과 같은 것을 사용하는 것입니다: https://passlib.readthedocs.io/en/stable/ #

암호화 코드를 안전한 방법으로 작성하는 것은 실수하기 쉽습니다.가장 나쁜 점은 암호화되지 않은 코드의 경우 프로그램이 충돌한 이후 작동하지 않을 때 즉시 알아차릴 수 있다는 것입니다.암호화 코드를 사용하는 경우에는 시간이 지난 후에야 데이터가 손상된 경우가 많습니다.그러므로 나는 그 주제에 대해 잘 아는 다른 사람이 쓴 패키지를 사용하는 것이 좋다고 생각합니다. 그리고 그것은 전투 테스트 프로토콜에 기초한 것입니다.

또한 passlib에는 사용이 편리하고 오래된 프로토콜이 고장난 경우 새로운 암호 해싱 프로토콜로 업그레이드하기 쉬운 몇 가지 좋은 기능이 있습니다.

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

3 기준으로 3.4 hashlib표준 라이브러리의 모듈에는 "보안 암호 해싱을 위해 설계된" 주요 파생 기능이 포함되어 있습니다.

따라서 다음을 사용하여 생성된 소금과 함께 다음 중 하나를 사용합니다.

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

참고:

  • PBKDF2의 16바이트 솔트와 100,000회 반복 사용은 Python 문서에서 권장하는 최소 숫자와 일치합니다.반복 횟수를 더 늘리면 해시의 계산 속도가 느려지기 때문에 안전성이 높아집니다.
  • os.urandom합니다.
  • hmac.compare_digesthmac.compare_digest에 사용되는is_correct_password , , 으로 입니다.==줄은 조작할 수 있지만 단락 능력이 없어 타이밍 공격에 면역이 됩니다.그것이 보안상의 가치를 추가로 제공하지는 않겠지만, 그것도 아프지 않아요. 그래서 제가 직접 가서 사용해봤습니다.

좋은 암호 해시 및 암호 해시에 적합한 다른 함수 목록을 만드는 방법에 대한 이론은 https://security.stackexchange.com/q/211/29805 을 참조하십시오.

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

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

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

추적(가장 최근 통화 마지막):
", ", 줄 1", 인 1",
=hashed_password= hashlib.sha512(비밀번호 + 소금).
는 hashing 개체는 - 해싱하기 인코딩되어야 합니다 유니코드 유형 오류 has 합니다 인코딩되어야 be - 해싱하기 before 에 전에 인코딩되어야 합니다.

passlib은 기존 시스템에서 저장된 해시를 사용해야 하는 경우 유용할 것으로 보입니다.형식을 제어할 수 있는 경우 bcrypt 또는 scrypt와 같은 현대 해시를 사용합니다.이때 bcrypt는 python에서 사용하기가 훨씬 쉬운 것 같습니다.

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

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

참고 항목:Python에서 암호 및 salt에 대한 해시를 생성하기 위해 scrypt를 사용하는 방법

오래된 실을 되살리고 싶지는 않지만...최신 보안 솔루션을 사용하고 싶은 사람은 아르곤2를 사용합니다.

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

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

이전에도 NodeJ에서 동일한 작업을 수행했습니다.

 echo "console.log(require('crypto').createHmac('sha256', 'salt').update('password').digest('hex'))" | node

python에서는 다음과 같습니다.

python3 -c 'import hashlib;import base64;import hmac;print(hmac.new(b"salt", "password".encode(), hashlib.sha256).hexdigest())'

그리고 이와 동등한 셸 명령어는 다음과 같습니다.

echo -n "password" | openssl sha256 -hmac "salt"

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

반응형