해시 함수(Hash Funtion)란?

728x90

 

해시 함수는 소프트웨어의 성능과 보안을 책임지는 매우 중요한 요수 중 하나이며, 데이터양이 많아져도 일관된 성능을 보장하는 구조로 설계할 수 있고 민감한 데이터의 변조를 막을 수 있기 때문입니다.

 

해시 함수(Hash Function)란?

알고리즘의 한 종류로써 임의의 입력값을 입력받아 항상 고정된 길이의 해시 값으로 변환하는 함수입니다.

변환 전 입력값은 문자, 숫자 등 거의 모든 형태의 입력값을 사용할 수 있습니다. 변환 후 데이터 값을 해시 값이라고 하며 바이너리 형태로 반환됩니다. 이러한 과정을 해싱(Hashing)이라고 하며 해싱에서 사용하는 함수를 해시 함수(Hash Function)라고 합니다.

 

특징

  • 입력값이 동일하면 계산한 결과값도 동일합니다.
  • 입력값의 길이와 상관없이 해시 값의 길이는 동일합니다.
  • 서로 다른 입력값이 동일한 해시값을 만들확률은 낮습니다.
  • 해시 값으로 입력값을 복원하는 방법은 불가능해야 합니다. (제1 역상공격)
  • 서로 다른 입력값으로 같거나 비슷한 해시 값을 찾는 방법이 불가능해야 합니다. (제2 역상공격)

 

해시 함수의 종류

 

1. MD5(Message-Digest algorithm 5)

90년대 사용해온 알고리즘으로 128비트 암호화 해시 함수입니다.

하지만 해시 충돌이라는 결함을 발견하게 되어 거의 사용되지 않습니다.

더보기

💡 해시 충돌이란?

해시 충돌을 만들 수 있다는 것은 서로 다른 두 값이 같은 해시 값을 만드는 상황을 말합니다. 그래서 해시 충돌이 가능한 해시 함수로 비밀번호를 저장하면, 저장된 것과 다른 비밀번호를 가지고 로그인을 할 수도 있습니다.

 

2. SHA-1(Secure Hash Algorithm-1)

최대 2^64비트 데이터를 입력값으로 사용할 수 있고, 고정된 160비트의 해시 값을 생성합니다.

MD5와 비교했을 때 8글자 더 길다는 것(SHA-1은 40글자) 외엔 다른 특징이 없으며 해시 이것또한 해시 충돌을 발견했기 때문에 권장하진 않습니다.

 

3. SHA-2(Secure Hash Algorithm-2)

해시 함수 하나를 지칭하지 않으며 SHA-256, SHA-384, SHA-512등 여러 해시 함수를 가리킵니다.

SHA-1보다 안전하기 때문에 SHA-1의 취약점이 발견된 이후부터는 가장 많이 사용되는 해시 함수입니다.

SHA-256은 64글자, SHA-512는 128글자로 SHA-1보다 긴 길이를 사용합니다.

아래 사이트는 입력 값을 SHA-256방식으로 변환해주는 사이트입니다.

https://www.convertstring.com/ko/Hash/SHA256

 

SHA256 해시 - 온라인 SHA256 해시 생성기

 

www.convertstring.com

💡 속도 비교
안전한 해시함수일수록 더 긴 길이를 사용한다는 것을 알 수 있습니다. 그렇기 때문에 해시 함수가 안전할수록 계산하는데 드는 비용도 커지게 됩니다.

 

사용 예

비밀번호와 같은 민감한 데이터를 보관할때 사용합니다.

import hashlib

hash_map = {}

def computeSHA256(str):
  hasher = hashlib.sha256()
  # 해시 함수 알고리즘을 알아도 비밀번호를 유추할 수 없게 salt 값을 추가
  hasher.update((str + 'salt').encode('utf-8'))
  return hasher.hexdigest()

while True:
  print('ID를 입력하세요: ')
  user_id = input()
  print('비밀번호를 입력하세요: ')
  password = input()

  if user_id in hash_map:
    if hash_map[user_id] == computeSHA256(password):
      print('{0}: 비밀번호가 일치합니다.'.format(user_id))
    else:
      print('{0}: 비밀번호가 일치하지 않습니다.'.format(user_id))
  else:
    hash_map[user_id] = computeSHA256(password)
    print('{0}: 비밀번호를 설정했습니다.'.format(user_id))

비밀번호를 그대로 해싱하지 않고, 비밀번호에 'salt'라는 문자열을 더한 후 해싱합니다.

 

💡 솔트(Salt)
입력값에 소금을 친다고 해서 솔트(Salt)라고 하며, 실무에서 비밀번호를 저장할 때 반드시 사용해야 하는 기술입니다.

솔트가 없다면 해킹으로 해시 값이 유출되어 두 가지 문제가 생길 수 있습니다.
1. 입력값이 같으면 결과값도 같기 때문에 원래 비밀번호를 유추 가능
2. 솔트가 없는 다른 웹 서비스에서도 해시 값 그대로 사용할 수 있는 문제

salt라는 간단한 문자열을 솔트로 사용했지만 개발을 하는 사람이 정해서 UUID나 또 다른 공식을 가진 문자열이 될 수 있습니다.

 

해시 함수의 개념과 종류를 알아보았고, 사용할때 종류 및 성능을 고려해 사용할 해시 함수를 정해야 합니다.

 

참고