[Alex] 데이터 장인의 블로그

[Python] - 암호화 라이브러리 hashlib 본문

Python

[Python] - 암호화 라이브러리 hashlib

Alex, Yoon 2021. 1. 5. 15:36

해시함수 hashlib  

프로젝트를 진행하던중 개인정보에 해당하는 데이터를 암호화하여 전달을 해야하는 경우가 생겼다. 데이터를 받는 대상 또한 어떤 암호화 방식을 사용했는지 알기만하면 데이터가 혼동되는 일은 없었기 때문에 복호화를 생각하며 프로그램을 짤 필요는 없었다. 때문에 간단하게 파이썬 라이브러리를 사용하여 데이터를 암호화하였다. 

 

대표적인 암호화 방식

(단방향 암호화 알고리즘) / 복호화 X 

  • sha3-224 

  • sha3-256

  • sha3-384 

  • sha3-512 

  • blake2b 

 

암호화 (Hash 처리) 시 주의해야할 점. 

어떤 언어를 사용하던지 암호화 방식은 통일되어 있다. 가장 많이 알려져있는 암호화 방식은 sha3-256, 512 인데 뒤 숫자만큼의 비트로 구성되어있다는 뜻이다.


다이제스트(Digest)

해시함수가 출력하는 결과(암호화 된 결과)를 다이제스트(Digest)라고 하는데, 위의 암호화 방식들은 각각 224, 256, 384, 512 bit 만큼의 출력 길이를 갖는 경우를 뜻하는 것이다. 즉, sha3-256 방식은 2의 256제곱만큼의 경우의 수가 만들어진다는 것이고 512방식은 2의 512제곱만큼의 경우의 수가 만들어진다는 것이다.


abc 값을 암호화하여 d 라는 결과가 나왔는데, bbc 값을 암호화하여 똑같이 d가 나오게 되는 경우를 '충돌'이라고 한다. 충돌을 방지하기 위해서는 암호화 해야하는 대상의 경우의 수와 output size(출력길이)를 고려하여 암호화 방식을 정해야한다. 즉, 내가 암호화해야하는 대상(ex. 카드번호)의 형식과 조건에 따라서 나타낼 수 있는 경우의 수가 다이제스트(Digest)의 출력 길이보다 짧아야(size가 작아야) 한다는 것을 의미한다.

 

충돌 위험이 가장 낮은 sha3-512 함수를 사용하려고 했지만, 그보다 더 좋은 blake 함수가 있다고 새롭게 알게되었기 때문에 해당 알고리즘을 사용하여 암호화 함수를 만들었다. 

[출처]

https://m.blog.naver.com/PostView.nhn?blogId=wideeyed&logNo=221472745532&proxyReferer=https:%2F%2Fwww.google.com%2F

나는 10자리의 숫자를 암호화 해야했다. 

ex) 5124823068 -> 암호화 -> 다이제스트(결과)

10자리의 숫자에서 발생할 수 있는 경우의 수는 10,000,000,000 (100억) 이다. 

이 경우 sha3-256만 사용해도 충분히 충돌을 막을 수 있다.

$ 2^{256} $ = 115,792,089,237,316,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000

$ 10^{10}< 2^{256} $

 

python의 blake2b함수는 다이제스트 바이트 수를 지정할 수 있었기 때문에 넉넉잡아 8bytes를 지정하여 암호화하였다.  

$ 10^{10}< 2^{8*8} $

def get_hash_value(reg_no, digest_bytes_size = 64, in_return_type='hexdigest'):
    # hash value 
    assert 1 <= digest_bytes_size and digest_bytes_size <= 64 
    blake = hashlib.blake2b(reg_no.encode("utf-8"), digest_size = digest_bytes_size)
    
    if in_return_type == 'hexdigest': return blake.hexdigest()
    elif in_return_type == 'number': return int(blake.hexdigest(), base = 16)
    return blake.digest()
    
get_hash_value(reg_no, 8 'hexdigest')   
# 결과값 : '44573b6ce2750304'

 

반응형
Comments