해시가 무엇일까?
암호화를 함에 있어서 해시는 항상 빠지지 않고 나오는 키워드인데 그럼 이 해시란게 간단하게 무엇일까?
해시함수는 임의의 길이를 갖는 메시지를 입력으로 고정된 길이의 해시값을 출력하는 일방향성을 가진 함수이다.
위 설명에서 해시함수가 가진 여러 특징이 있는데
1. 임의의 길이를 갖는 메시지로부터 고정 길이의 해시값을 출력한다.
어떠한 길이를 입력하더라도 항상 해시함수마다 갖는 고정된 해시값을 출력해야 한다. 해시함수가 결과로 16자리의 해시값을 출력한다고 가정하면 해시함수에 한 자릿수의 메시지든 50자릿수의 메시지든 항상 16자리의 해시값이 나온다.
2. 일방향성을 가진다.
해시함수에서 구별되는 특징 중 하나이다. 키를 기준으로 암호화하는 대칭키와 공개키에서는 decryption이 가능하지만 해시는 one-way 성질이 있기 때문에 원칙적으로 불가능하다.
3. 메시지가 다르면 해시값이 달라야 한다.
이건 당연한거 아닌가? 라는 생각이 들 수 있겠지만 해시함수는 다대일 대응 함수라 기본적으로 같은 값이 존재할 수 밖에 없다. 이렇게 다른 입력값으로부터 같은 해시값이 나오는 것을 충돌이라고 하는데 충돌이 발견되면 무결성을 보장할 수 없으므로 최대한 충돌을 발견하는 것이 어려워야 한다. 이를 collision resistance, 충돌 내성이라고 하는데 참고로 해시함수의 요구사항 3가지 중 하나이다.
식별과 인증 동시/분리 처리 + Hash
이번에는 앞서 했던 식별과 인증 동시 / 분리 처리에 Hash 처리를 한 로직에서 살펴보겠다. select * from member where id = 'user' and pw = md5('user_pass') 식별과 인증을 동시에 하는 case에 md5 Hash처리만..
ragdo11.tistory.com
식별 인증 처리를 할 때 Hash를 적용한 것을 알아보았을 때 md5를 사용했었다.
해시함수도 종류가 있는데 md5는 대표적으로 전용 해시함수 중 하나이다. 전용 해시함수는 해시값을 계산할 목적으로 새로 만든 함수를 말한다. 그 외로는 블록 암호를 기반으로 한 해시함수와 모듈러 연산을 기반으로 한 해시함수가 있다.
md5는 digest값으로(=해시값) 128비트를 출력하는데 이는 현재 충돌 공격에 내성을 갖기 짧다고 알려졌다. 그렇기에 현재 높은 보안이 필요한 경우는 권장되지 않는다고 한다.
한 가지 더 예시를 들자면 SHA 해시함수가 있겠다. SHA는 가장 널리 사용되는 해시함수로 SHA-1 과 SHA-2, SHA-3가 있다. SHA-1 160비트의 다이제스트 길이를 가지며 md4와 비슷한 구조, 수행을 하며 충돌 내성이 2005년에 이미 충돌 내성이 깨졌다. 현재 보편적으로 쓰이는 것은 SHA-2이며 224,256,384,512 비트의 다이제스트를 가지며 다이제스트 값에 따라 SHA-224, SHA-512 이런 식으로 불린다.
SHA-3(Keccak)가 나왔음에도 보편적으로 쓰이지 않는데는 역시 전환하려면 코드를 새로 짜야 되기 때문이 아닌가 싶다. 분명 SHA-1 충돌 내성이 깨진 건 2005년이라고 했지만 SHA-2가 권장 해시 표준이 된건 2011년, 전 세계적으로 SHA-2로 전환한 건 2016년 정도라고 한다. 그리고 소프트웨어에서 SHA-3의 속도는 SHA-512 보다 2배 가까이 느리다고 한다. (하드웨어에서는 빠르다고 함)
그럼 해시함수로 어떻게 비밀번호를 안전하게 비교할까?
비밀번호에 어떠한 암호도 적용하지 않고 그냥 교환하여 비교한다면 eavesdrop 같은 공격에 너무 간단히 당할 것이다. 그래서 비밀번호에 암호화를 적용해서 검증하는데 해시는 one-way라 복호화도 안 되기 때문에 검증할 계정의 비밀번호 다이제스트 값을 보관하고 있다가 사용자가 아이디와 비밀번호를 입력하면 입력한 비밀번호를 해시함수에 적용시켜 다이제스트값끼리 비교하여 정상적인 사용자가 맞는지 아닌지 검증하는 것이다!