Hash
Hash 는 단방향으로 암호화를 하는 기법입니다.
유저가 password 를 1234로 입력하고, DB에 password가 그대로 저장이 된다면,
해커가 DB에 접근하게 됐을때 모든 유저의 password 는 그대로 노출될 것입니다.
해시는 이처럼 원본 데이터를 암호화하기 위해 사용합니다.
단방향인 이유는 원본 데이터를 해싱해서 다이제스트(해시에 의해 암호화된 데이터)로 만들 수는 있지만,
다이제스트를 원본으로 복호화할 수는 없어야 하기 때문입니다.
ex) 1234 -> Hash -> 5b086ac2 (o)
ex) 1234 <- Hash <- 5b086ac2 (x)
Hash 의 단점
1. 동일한 원본 데이터를 해싱하면 동일한 해시값이 반환된다.
유저1과 유저2는 1234 로 같은 비밀번호를 사용합니다.
유저1: 1234 - 03AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4
유저2: 1234 - 03AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4
그러면 이렇게 같은 해시 값을 갖게 되는 것입니다.
해커 입장에서는 유저1과 유저2가 같은 비밀번호를 사용한다는 사실을 알 수 있고, rainbow table에 존재하는 값일 경우 쉽게 원본 데이터를 알 수 있습니다.
2. 무차별 대입 공격 (브루트포스)
Hash 자료구조는 검색 속도가 빨라서 Java에서도 HashMap, HashSet 을 사용합니다.
이는 해싱을 사용할 경우 해커도 빠르게 공격할 수 있는 기회를 줍니다.
물론 해시 알고리즘의 경우의 수가 다양해서 모두 입력하는데는 시간이 오래 걸리지만, 일정 범위를 지정해 놓고 공격하는 경우 쉽게 뚫릴 수 있다는 문제점이 존재합니다.
Salt
위처럼 hash의 문제를 방지하기 위해 사용하는 것이 salt 입니다.
Salt 는 해시 함수의 파라미터로 사용하기 전에 문자를 추가하여 암호화 하는 기법입니다.
해시 함수를 돌리기 전에 원문에 임의의 문자열을 덧 붙이는 것을 소금친다(salt)고 하는 것입니다.
솔팅을 하는 방법은
유저의 원본 데이터를 해싱하기 전에 각각 salt(난수의 문자)를 생성하여 원본 데이터에 추가해 주고, 해싱을 하는 것입니다.
1. 유저1은 b029dl02lazvswd23, 유저2는 lsdij2d972osncuw167 이라는 솔트값을 얻습니다.
2. 유저1은 1234b029dl02lazvswd23, 유저2는 1234lsdij2d972osncuw167 이라는 값을 해시 함수의 파라미터로 사용합니다.
유저1과 유저2는 서로 다른 해시 값을 갖게 됩니다.
유저1: 1234 - 10AA4F120C4E306CA8964633F33F4664EBC7BB0AE7D9E6688C01AAF1DAC9F74A
유저2: 1234 - 75CF8142283B80D6AF82422CD4BF9CD0D9B036036A6F709215E9B095053785D5