상세 컨텐츠

본문 제목

(자바) 단방향 해시 함수

Programming language/자바

by choiDev 2019. 2. 1. 16:16

본문

보통 프로그래머는 아래의 두 가지 중 한가지로 사용자의 패스워드를 저장한다.


 - 단순 텍스트(plain text)

 - 단방향 해시 함수(one-way hash function)의 다이제스트


단순 텍스트를 사용하는 것은 현업 에서는 말도 안되는 행위 이므로 단방향 해시 함수를 적용하는 것이좋다.


단방향 해시 함수란?

단방향 해시 함수는 수학적인 연산을 통해 원본 메시지를 변환하여 암호화된 메시지인 다이제스트를 생성한다. 원본 메시지를 알면 암호화된 메시지를 구하기는 쉽지만 암호화된 메시지로는 원본 메시지를 구할 수 없어야 하며 이를 '단방향성' 이라고 한다.


단방향 해시 함수의 문제점

대부분의 웹 사이트에서는 SHA-256 같은 해시 함수를 사용해 패스워드를 암호화해 저장하고 값을 비교하는 것만으로 충분한 암호화 메커니즘을 적용했다고 생각하지만 실제로는 다음과 같은 두 가지 문제점이 있다.


인식 가능성

동일한 메시지가 언제나 동일한 다이제스트를 갖는다면, 공격자가 전처리된 다이제스트를 가능한 많이 확보한 다음 이를 탈취한 다이제스트와 비교해 원본 메시지를 찾아내거나 동일한 효과의 메시지를 찾을 수 있다. 이와 같은 다이제스트 목록을 레인보우 테이블 이라 하고, 이와 같은 공격 방식을 레인보우 공격이라 한다. 게다가 다른 사용자의 패스워드가 같으면 다이제스트도 같으므로 한꺼번에 모두 정보가 탈취될 수 있다.


속도

해시 함수는 암호학에서 널리 사용되지만 원래 패스워드를 저장하기 위해서 설계된 것이 아니라 짧은 시간에 데이터를 검색하기 위해 설계된 것이다. 바로 여기에서 문제가 발생한다. 해시 함수의 빠른 처리 속도로 인해 공격자는 매우 빠른 속도로 임의의 문자열의 다이제스트와 해킹할 대상의 다이제스트를 비교할 수 있다.(MD5를 사용한 경우 일반적 장비를 이용하여 1초당 56억개의 다이제스트를 대입할 수 있다.)

이런 방식으로 패스워드를 추측하면 패스워드가 충분히 길거나 복잡하지 않은 경우에는 그리 긴 시간이 걸리지 않는다.


단방향 해시 함수 보완하기

솔팅(salting)

솔트는 단방향 해시 함수에서 다이제스트를 생성 할 때 추가되는 바이트단위의 임의의 문자열이다. 그리고 이 원본 메시지에 문자열을 추가하여 다이제스를 생성하는 것을 솔팅이라 한다. 


이 방법을 사용하면, 공격자가 다이제스트를 알아내더라도 솔팅된 다이제스트를 대상으로 패스워드 일치 여부를 확인하기 어렵다. 또한 사용자별로 다른 솔트를 사용한다면 동일한 패스워드를 사용하는 사용자의 다이제스트가 다르게 생성되어 인식 가능성 문제가 크게 개선된다.


솔트와 패스워드의 다이제스트를 데이터베이스에 저장하고, 사용자가 로그인할 때 입력한 패스워드를 해시하여 일치 여부를 확인할 수 잇다. 이 방법을 사용할 때에는 모든 패스워드가 고유의 솔트를 갖고 솔트의 길이는 32바이트 이상이어야 솔트와 다이제스트를 추측하기 어렵다.


키 스트레칭(key Stretching)

입력한 패스워드의 다이제스트를 생성하고, 생성된 다이제스트를 입력 값으로 하여 다이제스트를 생성하고, 또 이를 반복하는 방법으로

다이제스트를 생성할 수도 잇다. 이렇게 하면 입력한 패스워드를 동일한 횟수만큼 해시해야만 입력한 패스워드의 일치 여부를 확인할 수있다. 이것이 기본적인 키 스트레칭 과정이다.


잘 설계된 패스워드 저장 시스템에서는 하나의 다이제스트를 생성할때 어느정도의 시간이 소요되게 설정한다. 이는 억지 기법 공격으로 패스워드를 추측하는 데 많은 시간이 소요되도록 하기 위한 것이다.


관련글 더보기