Python
[Python] 해시(Hash) 알고리즘 : 안전한 비밀번호 암호화 구현하기
dev-grace
2024. 12. 23. 21:53
이번 포스트에서는 사용자 비밀번호를 안전하게 보호하기 위한 해시 알고리즘 구현 방법과 고려사항에 대해 다룰 예정이다.
1. 비밀번호 암호화의 필요성
현대 웹 서비스에서 사용자 비밀번호를 안전하게 보호하는 것은 필수이다. 암호화되지 않은 비밀번호는 다음과 같은 보안 위험을 초래할 수 있다.
1-1. 보안 위험
- 데이터베이스 유출 사고 발생 가능성
- 평문 저장 시 즉시 노출 위험
- 해킹으로 인한 사용자 정보 유출 위험
이러한 위험을 방지하기 위해 해시(Hash) 알고리즘을 사용한 암호화가 필요하다. 해시의 주요 장점은 다음과 같다.
1-2. 해싱의 장점
- 단방향 암호화로 원본 복원 불가
- 동일 입력값에 대한 일관된 해시값 생성
- 데이터베이스 저장 시 추가적인 보안층 제공
2. 암호화 구현 방법
2-1. bcrypt를 활용한 방법
import bcrypt
# 비밀번호 해싱
password = b"myPassword123"
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
# 비밀번호 검증
def verify_password(plain_password, hashed_password):
return bcrypt.checkpw(plain_password, hashed_password)
2-2. hashlib을 활용한 고급 해싱
import hashlib
import binascii
def hash_password(password):
# 솔트 생성 및 해싱
salt = b"unique_salt_per_user" # 실제 구현시 사용자별 고유값 사용
key = hashlib.pbkdf2_hmac(
'sha512',
password.encode('utf-8'),
salt,
100000 # 반복 횟수
)
return binascii.hexlify(key)
print(hashlib.algorithms_available)
# {'blake2b', 'blake2s', 'md5', 'md5-sha1', 'ripemd160', 'sha1', 'sha224', 'sha256', 'sha384', 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512', 'sha512_224', 'sha512_256', 'shake_128', 'shake_256', 'sm3'}
3. 구현 시 고려사항
3-1. 보안 고려사항
- 솔트(Salt) 값을 사용자별로 유니크하게 생성
- 충분한 해싱 반복 횟수 설정 (최소 100,000회 이상 권장)
- 안전한 해시 알고리즘 선택 (SHA-512, bcrypt 등)
3-2. 성능 고려사항
- 적절한 반복 횟수 설정으로 보안과 성능 밸런스 유지
- 해싱 작업은 CPU 자원을 많이 사용하므로 비동기 처리 고려
4. 실제 구현 예시
class UserAuth:
def __init__(self):
self.salt_rounds = 12 # bcrypt 보안 수준
def hash_password(self, plain_password):
return bcrypt.hashpw(plain_password.encode('utf-8'), bcrypt.gensalt(self.salt_rounds))
def verify_password(self, plain_password, hashed_password):
return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password)
def register_user(self, username, password):
hashed_password = self.hash_password(password)
# DB 저장 로직
return {"username": username, "password": hashed_password}
+) bcrypt의 salt_rounds는 해시를 생성할 때 수행되는 내부 반복 횟수를 결정하는 값이다.
이 값이 1 증가할 때마다 해싱 작업량이 2배로 증가한다.
예시)
- `rounds = 10`: 2¹⁰ = 1,024번 반복
- `rounds = 11`: 2¹¹ = 2,048번 반복
- `rounds = 12`: 2¹² = 4,096번 반복
- `rounds = 13`: 2¹³ = 8,192번 반복
따라서 salt_rounds 값이 높아질수록,
- 장점
- 보안 수준이 높아진다.
- 해시를 크래킹하는데 더 많은 시간과 컴퓨팅 자원이 필요하다.
- 무차별 대입 공격(Brute Force)에 대한 저항성이 증가한다.
- 단점
- 해시를 생성하는 시간이 기하급수적으로 증가한다.
- 서버의 CPU 사용량이 증가한다.
- 사용자 인증 시 대기 시간이 길어진다.
- 일반적으로 권장되는 값
- 최소 10 이상을 권장
- 서버 성능에 따라 10-14 사이의 값을 선택