이전 게시글에서 학습한 것과 같이 단방향 암호화에서 해싱 알고리즘을 통해서 암호화를 할 경우 같은 입력값을 넣을 경우 똑같은 출력값이 나온다. 즉, 동일한 평문에 대해 항상 동일 해시값을 갖는다. 따라서 특정 해시 알고리즘에 대하여 특정한 평문이 어떤 해시값을 갖는지 알 수 있다.
또한 애초에 해쉬 함수의 목적이 신속하게 데이터를 검색하기 위해 탄생했다. 그래서 속도가 중요하기 때문에, 대부분의 해쉬 함수는 충분히 빠르다.
그러나 이것이 오히려 보안에서는 이 빠른 게 오히려 공격자에게 장점으로 다가온다. 왜냐하면 가능한 모든 입력 값에 대한 출력 값을 정리해놓고, 정리해 놓은 출력 값과 실제 데이터베이스에 저장되어 있는 값을 일일히 비교하는 작업이 가능하기 때문이다. 해쉬 함수의 성능에 따라 1초에 몇억 번을 수행할 수 있다고 하니, 레인보우 테이블을 충분히 쌓아둔다면 해킹이 마냥 불가능하니는 않을 것 같다.
이러한 문제들을 보완하기 위해서 레인보우 테이블이 쓸모없게 하거나 레인보우 테이블을 만들 수 없도록 할순 없을까? 라는 아이디어에서 시작된 기술들인 솔팅(Salting)과 키 스트레칭(Key Stretching)이 나온 것이다.
하나씩 알아보자.
첫번째로 솔팅(Salting)이라는 기법이다. 복호화를 방해하기 위해 단방향 암호화시 솔트(Salt)를 뿌려 해커가 복호화 하는 것을 방해하는 방법이다. 즉, 암호화를 진행 할 때 본래 데이터에 추가적으로 랜덤한 데이터를 더해 이전의 해시값(출력값)과 다른 값을 가지도록 하는 것이다.
그 결과 두 명의 유저가 같은 비밀번호를 보유하고 있다고 하더라도 서로 다른 해쉬값을 가지게 되는 것이다.
그래서 최초 암호화 시에 사용한 솔트 값을 데이터베이스에 잘 저장하고있다가 로그인 요청이 들어올때 마다 해당 유저의 솔트를 사용하여 입력값을 암호화 한 뒤 데이터베이스에 저장되어있는 다이제스트(암호화 된 비밀번호, 해쉬값)와 비교해야한다.
해당 기법은 단방향 암호화를 통해 해쉬값을 계산 한 뒤, 그 해쉬값을 또 다시 해시하고 또 이를 반복하는 방식이다. 최근 일반적인 장비로도 1초에 50억 개 이상의 해시값을 비교할 수 있다. 하지만 키 스트레칭을 적용하면 동일 장비에서 1초에 5번 정도만 비교할 수 있다. GPU(Graphics Processing Unit)를 사용하더라도 수백에서 수천 번 정도만 비교할 수 있다. 즉, 레인보우 테이블 공격으로 인한 위험성을 감소시킬 수 있는 것이다.
이렇게 되면 키 스트레칭을 통해 레인보우 테이블을 쓸모없게 할 수 있고 솔팅을 통해 레인보우 테이블을 만들 수 없도록 할 수 있는 것이다.