데이터 보안은 모든 IT 기업이 가장 중요하게 여기는 핵심 과제입니다. 데이터를 보호하고 무결성을 검증하기 위해 다양한 해싱(Hashing) 기법이 사용되고 있습니다. 이 글에서는 Python의 hashlib 모듈을 활용해 SHA 계열 해시 알고리즘을 사용하는 방법을 자세히 알아보겠습니다.
해시(Hash)란 무엇인가?
해시 함수는 가변 길이의 바이트 시퀀스를 입력받아 고정된 길이의 시퀀스로 변환하는 함수입니다. 중요한 특징은 원본 데이터(입력 바이트)를 다시 복원하기가 매우 어렵다는 점입니다. 예를 들어, 입력값을 x, 해시 함수를 f라고 할 때 f(x)를 계산하는 것은 빠르고 간단하지만, 그 결과로부터 x를 되찾아내는 것은 사실상 불가능에 가까운 작업입니다.
해시 함수의 반환값은 해시(hash), 체크섬(checksum), 해시 값(hash value), 메시지 다이제스트(message digest) 등으로 불립니다.
이를 정리하면 다음과 같습니다.
- 일방향성: 해시 값에서 원본 데이터를 역산할 수 없습니다.
- 고정 출력 길이: 입력 크기와 관계없이 항상 일정한 길이의 결과를 반환합니다.
- 빠른 연산 속도: 해시 값을 생성하는 과정은 매우 효율적입니다.
예를 들어 "Hello World"라는 메시지를 SHA1 해시 함수로 변환하면 다음과 같은 결과가 나옵니다.
0a4d55a8d778e5022fab701977c5d840bbc486d0
해시 함수의 실무 활용 분야
실제 환경에서 해시 함수는 암호화 알고리즘, 디지털 서명, 지문(fingerprint) 인식, 비밀번호 저장 등 다양한 영역에서 폭넓게 활용됩니다. Python 개발자 입장에서는 다음과 같은 경우에 해시 함수가 필요합니다.
- 데이터나 파일의 중복 여부 확인
- 공개 네트워크를 통해 데이터를 전송할 때 무결성 검증
- 데이터베이스에 비밀번호를 안전하게 저장
주요 해시 알고리즘: MD5 vs SHA
가장 널리 사용되는 두 가지 해시 알고리즘은 다음과 같습니다.
MD5 - MD5(Message Digest Algorithm)는 128비트 해시 값을 생성합니다. 다만 몇 가지 보안 취약점이 발견되어 현재는 주로 데이터 무결성 검사 용도로만 사용됩니다.
SHA - SHA(Secure Hash Algorithm) 계열에는 여러 알고리즘이 포함되어 있으며, 미국 연방 정보 처리 표준(FIPS)에 따라 개발되었습니다. MD5보다 훨씬 안전하여 암호화 응용 프로그램을 포함한 다양한 분야에서 널리 사용됩니다. 이 알고리즘들이 생성하는 메시지 길이는 160비트에서 512비트까지 다양합니다.
SHA1 해시 알고리즘 사용법
SHA는 SHA1, SHA224, SHA256, SHA384, SHA512 등 여러 알고리즘을 포괄하는 명칭입니다. 그중 SHA1은 MD5보다 안전하다고 평가받아 많은 분야에서 활용되고 있습니다.
먼저 해싱 알고리즘을 사용하려면 hashlib 모듈을 임포트해야 합니다.
import hashlib
현재 hashlib 모듈에서 사용 가능한 알고리즘 목록을 확인하려면 다음과 같이 실행합니다.
>>> print(hashlib.algorithms_available)
{'sha3_256', 'sha3_224', 'sha1', 'blake2b', 'sha512', 'dsaEncryption', 'dsaWithSHA', 'DSA', 'md5', 'sha384', 'sha224', 'sha3_384', 'ecdsa-with-SHA1', 'DSA-SHA', 'SHA1', 'md4', 'SHA256', 'MD4', 'sha3_512', 'whirlpool', 'sha256', 'shake_256', 'SHA', 'RIPEMD160', 'shake_128', 'SHA512', 'ripemd160', 'SHA224', 'sha', 'blake2s', 'SHA384', 'MD5'}위 목록은 OpenSSL을 통해 제공되는 알고리즘까지 포함한 것입니다. 반면, 어떤 파이썬 환경에서든 항상 사용 가능한 알고리즘만 확인하려면 algorithms_guaranteed를 사용합니다.
>>> print(hashlib.algorithms_guaranteed)
{'sha3_512', 'sha256', 'sha3_256', 'shake_256', 'sha3_224', 'sha1', 'blake2b', 'sha512', 'md5', 'shake_128', 'sha384', 'sha224', 'sha3_384', 'blake2s'}SHA1 해시 생성 예제
간단한 프로그램을 통해 SHA1 알고리즘의 동작을 살펴보겠습니다.
import hashlib hash_obj = hashlib.sha1(b'Hello, Python!') print(hash_obj.hexdigest())
출력 결과
00d375a3693fde63e9540b91656c6ac5b5341f7c
16진수 문자열이 아닌 바이트 시퀀스 자체가 필요하다면 digest() 메서드를 사용하면 됩니다.
import hashlib hash_obj = hashlib.sha1(b'Hello, Python!') # 바이트 시퀀스 생성 print(hash_obj.digest())
출력 결과
b'\x00\xd3u\xa3i?\xdec\xe9T\x0b\x91elj\xc5\xb54\x1f|'
문자열 인코딩 주의사항
위 예제에서 문자열 리터럴 앞에 b를 붙인 이유는 문자열을 바이트로 변환하기 위해서입니다. 해시 함수는 오직 바이트 시퀀스만 매개변수로 받기 때문입니다.
콘솔에서 입력받은 문자열을 해싱하려면 반드시 encode() 메서드로 문자열을 바이트 시퀀스로 인코딩해야 합니다.
import hashlib
mystring = input('Enter string to hash: ')
hash_obj = hashlib.sha1(mystring.encode())
print(hash_obj.hexdigest())출력 결과
Enter string to hash: Hello, TutorialsPoint b20d14ead3e50552fc1f1cd96696b111a163dffa
마무리
Python의 hashlib 모듈을 사용하면 SHA1을 비롯한 다양한 해시 알고리즘을 몇 줄의 코드로 손쉽게 구현할 수 있습니다. 단, 보안이 중요한 비밀번호 저장 등에는 SHA1보다 더 강력한 SHA256 또는 SHA512 같은 알고리즘을 사용하는 것이 권장됩니다. 해시 함수의 특성과 용도를 정확히 이해하고 상황에 맞는 알고리즘을 선택하는 것이 안전한 데이터 관리의 첫걸음입니다.