학습 로그/Python3

D+42 [Python] hashlib 뭐야? 어떻게 활용해야 할까?

goodjob^^ 2026. 6. 8. 07:31

ㅇ 일 자 : 2026년 6월 8일(월)

hashlib 어떻게 활용해야 할까?

""hashlib""은 파이썬 표준 라이브러리로, 데이터의 무결성을 검증하거나 비밀번호 등을 안전하게 단방향 암호화할 수 있는 다양한 해시 알고리즘(MD5, SHA-1, SHA-256, SHA-512 등)을 제공한다.
파이썬을 설치하면 별도 설치 없이 import hashlib로 바로 사용할 수 있다.
 

1. 해시(Hash)의 기초 개념

  • 단방향성 (One-way) : 데이터로부터 해시값을 생성할 수는 있지만, 해시값으로부터 원래 데이터를 역산하는 것은 불가능 하다
  • 고정된 길이 : 입력값의 길이에 상관없이 항상 동일한 길이의 해시값을 출력한다.
  • 눈사태 효과 (Avalanche Effect) : 입력값이 단 1글자만 달라져도 완전히 다른 해시값이 생성된다.

2. hashlib 기본 사용법

2.1 지원하는 해시 알고리즘 확인 
시스템에서 사용할 수 있는 알고리즘 목록을 확인할 수 있다

import hashlib

# 항상 제공되는 안전한 알고리즘 목록
print("guaranteed:", hashlib.algorithms_guaranteed)

# 현재 시스템의 OpenSSL 라이브러리에 따라 사용 가능한 전체 알고리즘 목록
print("available:", hashlib.algorithms_available)

 
2.2 문자열 해시값 생성 (기본 공식)
해시 함수에 문자열을 전달할 때는 반드시 바이트(bytes) 객체로 인코딩. 파이썬의 기본 문자열은 유니코드이기 때문

import hashlib

# 1. 대상 문자열 정의
message = "Hello, Python!"

# 2. SHA-256 해시 객체 생성 및 데이터 업데이트 (바이트로 인코딩 필수)
hash_object = hashlib.sha256()
hash_object.update(message.encode('utf-8'))

# 3. 해시 결과값 추출
# - digest(): 바이트 형태의 결과값 반환
# - hexdigest(): 16진수 문자열 형태의 결과값 반환 (가장 많이 사용됨)
hex_result = hash_object.hexdigest()

print(f"원본: {message}")
print(f"SHA-256 해시값: {hex_result}")
# 출력: a6ef198a0d0a7900b92f7411639f76a54911bf047f3e8f8045610ec87019a69a

 
2.3 한 줄로 축약해서 표현하기
생성과 인코딩을 한 번에 처리하는 간결한 문법

import hashlib

# 생성자 내부에 바로 바이트 데이터를 넘겨 처리
hex_result = hashlib.sha256(b"Hello, Python!").hexdigest()
print(hex_result)

 
접두어 b를 붙이는 형태(b"string")는 영문/숫자 리터럴에만 작동. 한글 등이 포함된 문자열은 반드시 .encode('utf-8')을 사용
 

3. 대용량 파일 해시 생성하기

용량이 큰 파일은 한 번에 메모리에 올리면 메모리 부족 오류가 발생할 수 있다. 파일을 조각(Chunk) 단위로 읽어서 해시 객체를 점진적으로 업데이트 한다.

import hashlib

def calculate_file_hash(filepath, algorithm="sha256"):
    # 명시된 알고리즘 이름으로 해시 객체 동적 생성
    hash_obj = hashlib.new(algorithm)
    
    # 64KB(65,536 바이트) 크기로 파일을 분할해서 읽기
    chunk_size = 65536
    
    with open(filepath, 'rb') as f:
        while chunk := f.read(chunk_size):
            hash_obj.update(chunk)
            
    return hash_obj.hexdigest()

# 사용 예시:
# file_sha256 = calculate_file_hash("large_video.mp4")
# print(file_sha256)

 

4. 비밀번호 암호화와 보안 가이드 

단순히 hashlib.sha256("password".encode()) 형태로만 비밀번호를 암호화하면 레인보우 테이블(Rainbow Table)이라는 이미 계산된 해시 테이블을 통해 쉽게 해킹당할 수 있다. 이를 방지하기 위해 반드시 솔트(Salt)와 키 스트레칭(Key Stretching)을 사용.
4.1 솔트(Salt)란?
비밀번호 해싱 전에 무작위 문자열(솔트)을 덧붙여 해싱하는 기법, 사용자마다 다른 고유의 솔트를 사용해야 보안이 유지됨

import hashlib
import os

password = "my_secure_password"

# 1. 안전한 무작위 솔트 생성 (최소 16바이트 이상 권장)
salt = os.urandom(16)

# 2. 패스워드와 솔트를 합쳐서 해싱
hash_obj = hashlib.sha256()
hash_obj.update(salt)
hash_obj.update(password.encode('utf-8'))

key = hash_obj.hexdigest()

print(f"솔트 (HEX): {salt.hex()}")
print(f"최종 저장할 해시값: {key}")

 
 
※ 검증할 때 동일한 솔트가 필요하므로, 데이터베이스에는 [생성된 솔트]와 [최종 해시값]을 둘 다 저장해야 함
 
4.2.  PBKDF2 알고리즘 사용 (권장 표준)
hashlib.pbkdf2_hmac은 솔트 적용과 키 스트레칭(수만 번 반복 해싱)을 내부적으로 안전하게 처리해 주는 표준 API 이다.

import hashlib
import os

password = "user_password_123"

# 1. 무작위 솔트 생성
salt = os.urandom(16)

# 2. PBKDF2를 사용하여 비밀번호 해싱
# 매개변수: (알고리즘명, 비밀번호바이트, 솔트, 반복횟수, 출력바이트길이)
dk = hashlib.pbkdf2_hmac(
    'sha256', 
    password.encode('utf-8'), 
    salt, 
    100000, # 반복 횟수 (기본 10만 번 이상 권장, 숫자가 높을수록 느리지만 안전함)
    dklen=32 # 출력되는 키의 길이 (바이트 단위)
)

# 데이터베이스에 저장할 값들
stored_salt = salt.hex()
stored_hash = dk.hex()

print(f"DB 저장용 솔트: {stored_salt}")
print(f"DB 저장용 비밀번호 해시: {stored_hash}")

 
4.3 비밀번호 검증 (Verification) 과정
사용자가 로그인할 때 입력한 비밀번호가 올바른지 검증하는 구조

def verify_password(input_password, stored_salt_hex, stored_hash_hex):
    # 1. DB에서 가져온 16진수 문자열 솔트를 원래 바이트로 복원
    salt = bytes.fromhex(stored_salt_hex)
    
    # 2. 동일한 매개변수와 솔트로 입력된 비밀번호를 다시 해싱
    dk = hashlib.pbkdf2_hmac(
        'sha256', 
        input_password.encode('utf-8'), 
        salt, 
        100000,
        dklen=32
    )
    
    # 3. 해시값 일치 여부 비교
    # 단순 == 비교보다 timing attack을 방지하는 hmac.compare_digest() 사용이 더 안전합니다.
    import hmac
    return hmac.compare_digest(dk.hex(), stored_hash_hex)

# 검증 테스트
is_valid = verify_password("user_password_123", stored_salt, stored_hash)
print(f"비밀번호 검증 결과: {is_valid}") # True

 

5. 핵심 요약 및 주의 사항

  • 인코딩 필수 : hashlib 함수는 항상 유니코드 문자열이 아닌 bytes 타입을 요구하므로 반드시 .encode('utf-8')을 거치거나 바이트 데이터를 사용 한다.
  • MD5 및 SHA-1 사용 지양 : 이 알고리즘들은 이미 충돌 취약점이 발견되었다. 보안이 중요한 데이터(예: 비밀번호)에는 절대 사용하지 말고 무결성 체크 등의 단순 작업에만 제한적으로 사용할 수도 있다.
  • 비밀번호 저장 최선책 : 단순 SHA-256 사용은 위험하다. 최소한 파이썬 표준 라이브러리의 hashlib.pbkdf2_hmac을 사용하거나, 외부 패키지인 bcrypt 또는 argon2 라이브러리를 추가하여 활용하는 것이 최선의 보안 대책이다.

 " hashlib " 은 비전공자들에게 생소하고 즉시 활용하기는 다소 어렵다. 용어부터가 이해하기 어렵기 때문에 소스코드를 통해 이해하고자 인공지능 참고하여 실습 및 공부했다. 당장 활용하기에는 쉽지 않더라도 작성하면서 고민도 해 보고 이해하려고 자료도 찾아보는 등의 경험을 했다는 것만으로도 도움이 되는것 같다. 우리가 자주 사용하는 비밀번호 체계 등이 이러한 코드에서 구현되고 있다는 것은 비전공자에게 생소하기도 하다. 참으로 어려운 활용법이다. 이해하는데 시간이 걸리겠다.
그래도 "도전은 계속된다."