Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

MyPrograming

해시와 솔트 본문

Python/Python Study

해시와 솔트

SeongWon 2020. 2. 26. 20:38
반응형

이전에 작성한 RegisterView.py와 LoginView.py에 쓰여진 salt와 hashed_pw..?

 

salt, hashed_pw = hashing_password(user_pw)

 

이렇게 별도로 작성하고 import하여 쓴 것이다.

import string
import random
import hashlib
import base64
from django.contrib.auth.hashers import pbkdf2

def hashing_password(user_pw):
    count = random.randint(16, 21)
    string_pool = string.ascii_letters + string.digits + string.punctuation
    salt = "".join(random.choices(string_pool, k=count))

    hash = pbkdf2(user_pw, salt, 10000, digest=hashlib.sha256)
    hashed_pw = base64.b64encode(hash).decode('ascii').strip()

    return salt, hashed_pw

 

 


 

1. 해시(hash)?

예시로 설명하면 평문의 비밀번호 "jeongpro1234"를 해시함수(해시 알고리즘)를 이용하여 고정된 길이의 암호화된 문자열로 바꿔 버리는 것이 해시를 이용한 암호화 기법이다.

 

1-1. 해시(hash) = 암호화(Encryption)?

 

둘 다 암호화 기법이지만 Hash 단방향 암호화 기법이고 Encryption은 양방향 암호화 기법이다.

쉽게 설명하면 Hash는 평문을 암호화된 문장(텍스트)으로 만들어주는 기능을 하고,

Encryption은 평문을 암호화된 문장(텍스트)로 만들어주는 기능을 하고 + 암호화된 문장을 다시 평문으로 만드는 복호화 기능도 한다.

 

1-2. 해시의 주의점.

 

1) 해시 알고리즘 및 밑에서 얘기할 암호화 알고리즘은 종류가 다양하며, 알고리즘은 모두에게(해커에게도) 공개되어있다.

대신 알고리즘에 취약점이 발견되어 취약점에 의해 보안이 뚫리면 알고리즘을 만든 사람(암호학자)이 형사 처벌(?)된다. 따라서 알고리즘을 만들 때 엄청나게 많은 검증을 거치게 되고, 많은 개발자들이 검증된 것들을 사용한다.

 

2) 해시 알고리즘마다 Hash 길이가 다르고 이미 보안이 뚫린 해시 함수가 존재한다.

MD5, SHA-1, HAS-180은 사용하면 안된다. SHA-256, SHA-512등을 사용하기를 권고함. 참고로 SHA-512가 보안이 더 좋다.

 

3) 해시 알고리즘은 특정 입력 대해 항상 같은 해시 값을 리턴한다.

이 점을 이용해서 '인증'이 가능하다. 어떤 입력인지 몰라도 해시함수를 이용해서 해시된 값이 일치하면 입력이 같다는 것이 입증된다.

 

4) 해시된 값은 입력이 다른 값이지만 같을 수 있다.

입력은 만들어낼 수 있는 평문이 길이제한이 없다면 무한정으로 만들어 낼 수 있지만 해시된 값은 항상 고정된 길이의 값으로 나타내므로 한계가 있기 때문에 다른 입력이지만 해시된 값이 같은 경우가 나타날 수 있다

 

1-3 해시를 통한 인증 관련 흐름

 

1. 사용자가 계정을 생성한다.

2. 사용자의 비밀번호는 해싱되어 데이터베이스에 저장된다. 원본 패스워드는 하드 디스크 어디에도 기록되지 않는다.

3. 사용자가 로그인을 시도 할 때 사용자가 입력한 패스워드의 해시값이 데이터베이스에 저장된 값과 동일 한지 비교 한다.

4. 만약 해시값이 동일하면, 사용자는 로그인에 성공하고 아니면 잘못된 값을 입력했다고 알려준다.

5. 로그인을 계속 시도 하는경우 3~4번 과정을 반복한다.

 


이러한 과정을 거친다 해서 해시함수를 이용한 변환이 완벽한 보완에 가깝다고 말할 수 없다.

왜냐하면 해커가 무차별적으로 임의의 값을 엄청한 횟수로 입력하면서 비밀번호를 알아낼 수도 있기 때문이다. 이러한 점을 보완하기 위해서 비밀번호와 함께 솔트(salt)값을 넣는 방법이 존재한다.

 


 

2. 솔트(salt)?

일종의 랜덤 텍스트로, 사용하는 주된 목적은 비밀번호에 솔트를 섞은 후 함께 해시하여 레인보우 테이블 자체를 무의미하게 만드는 것이다. 

 

무작위 문자열을 비밀번호를 해싱하기 전에 붙여서 해쉬 값을 무작위로 만들 수 있다. 인증을 진행할 때 비밀번호가 동일한지 확인을 하기 위해서는 솔트값이 필요 한데 이 값은 보통 사용자 계정을 저장하는 데이터베이스에 비밀번호 해쉬값과 같이 있거나 해쉬값으로 변환 되어 저장하고 있다. 

참고로 솔트값을 넣는 방법은 다양하다. (비밀번호 양쪽에 솔트값을 넣고 해시함수를 수행하는 방법, 한쪽에 넣고 해시함수를 수행한다음 다시 솔트값을 넣고 수행하는 방법등)

따라서 솔트값을 알아도 해커가 운이 정말 좋아도 한 명정도의 개인정보를 알아갈 뿐, 개인정보 유출사태는 일어나지 않게 된다.

 


이러한 해시와 솔트를 구축하기 위해 직접 코딩하여 수작업 하는 방법도 있다.

하지만 이미 이용하기 편하도록 검증된 해시 함수와 솔트를 이용하는 방법과 해시 함수를 여러번 적용하는 방법을 이용하는 key derivation function가 존재한다.

 

pbkdf2 : 솔트값과 해시함수의 반복횟수등을 지정할 수 있다.

bcrypt : 패스워드를 위해 탄생해서 아주 강력한 해시 알고리즘이 적용된다

 


 

해시와 솔트를 통해 암호화된 비밀번호는 다음과 같이 DB에 저장된다.

 

실제 DB에 저장된 비밀번호

반응형

'Python > Python Study' 카테고리의 다른 글

Docstring & 어노테이션  (0) 2020.07.27
Static File & Media File  (0) 2020.04.08
User 모델 확장  (0) 2020.04.05
Pycharm views.py 복습  (0) 2020.02.17
URLconf 2계층 분류  (0) 2020.01.30