사내에서 담당 개발 중인 채용 사이트의 admin페이지 계정이 평문으로 DB에 저장되어있는 것을 확인하였다.
지난주 면접(N사)에서 암호화와 관련된 질문을 받았던 적이 있어서 채용 사이트 어드민 계정 암호화를 진행하면서 정리해보자.
두 가지 암호화 기법
Hash와 Encryption
두 가지 모두 암호화 기법이지만 Hash는 단방향 암호화 기법이며 Encryption은 양방향 암호화 기법이다.
따라서 Hash는 암호화가 된 값을 다시 원래의 평문으로 돌리는 것이 불가능하지만 Encryption은 가능하다.
Salt
평문에 임의의 값들을 덧붙여 해시함수에 넣는 것을 말한다. (패스워드에 소금을 치는 것.)
이렇게 하면 값의 길이가 길어져 Rainbow Table(해시 함수를 사용하여 만들 수 있는 값들을 왕창 저장한 표, db)를 이용해도 쉽게 알아내지 못하도록 할 수 있다.
프로젝트에 적용할 암호화 기법
나는 spring security 프로젝트의 BycryptPasswordEncoder를 사용하고자한다.
사용한 이유는 다음과 같다.
- 해당 클래스는 Bcrypt 해시 함수를 사용하며 bcrypt 해시 함수는 패스워드 암호화를 위해 만들어진 아주 강력한 해시 알고리즘임.
- salt를 사용함.
로그인 시 db의 패스워드와 비교하는 로직은 다음과 같다.
- 입력받은 password를 암호화.
- 암호화한 값과 DB의 암호화된 값을 비교.
→ DB의 암호화된 패스워드를 복호화하여 입력받은 패스워드와 비교할 수도 있지 않을까?라는 생각이 들 수 있지만 해시알고리즘을 사용하기 때문에 한번 암호화된 값은 복호화가 불가능하다. 따라서 동일한 값을 해시 함수에 넣을 경우 항상 동일한 해시 값을 리턴하는 것을 이용해 인증을 한다.
→임의의 salt값이 붙어져서 암호화 되기 때문에 같은 패스워드라도 암호화된 값은 매번 달라질 수 있다. 따라서 equals가 아닌 클래스에서 지원하는 matches 메소드를 사용하여 비교한다.
해시 함수는 완벽하지 않다.
충돌이 발생할 수 있으며 충돌이 발생한다는 것은 다른 값에 대해 동일한 해시값이 발생할 수도 있다는 것이다. 따라서 동일한 해시값이 적게 발생하는 해시 함수가 좋은 함수이다.
또한 암호화가 아닌 검색(조회) 속도 향상을 위해 만들어진 것이기 때문에 부르트포스 방법으로 임의의 값을 넣어 대면 해킹을 당할 수도 있다.
참고자료