해싱은 가장 많이 쓰이는 암호화 방식중 하나이다. 복호화가 가능한 다른 암호화 방식들과 다르게 해싱은 암호화만 가능하다.
*복호화(디코딩): 부호화(encoding)된 데이터를 부호(code)화 되기 전 형태로 바꾸어, 사람이 읽을 수 있는 형태로 되돌려놓는 것이다.
해싱은 해시 함수(Hash Function)을 사용하여 암호화를 한다.
SHA1 함수를 직접 사용해볼 수 있다.
전성훈은 개발자가 된다. -> E0D5111F1D9DD0C3D6F354B99928C1D28A958ED7
전성훈은 개발자가 될 것이다. -> 6CDA30ACD91AC6F1C5A60A5E957D7AFC5ACCE669
전성훈은 개발자가 될 것이다. -> 6CDA30ACD91AC6F1C5A60A5E957D7AFC5ACCE669
= 동일한 문자열에 동일한 SHA1 함수를 적용하니 해시 값이 같은 것을 볼 수 있다.
항상 같은 결과값이 나온다는 특성을 이용하면 이 또한 복호화가 가능할 것이라고 생각된다. 사실 해시 함수를 거치기 이전의 값을 알아낼 수 있도록 기록해놓은 표인 레인보우 테이블 이라는 것이 존재한다.
이 때 솔트(Salt) 활용하면 된다. 해싱 이전 값에 임의의 값을 더해(소금을 쳐서) 데이터가 유출 되더라도 해싱 이전의 값을 알아내기 어렵게 만드는 방법이다.
솔트를 사용하게 되면 암호화가 이중으로 된 것이기 때문에 해싱 값이 유출되더라도 솔트와 함께 유출 된 것이 아니라면 이전의 값을 알아내는 것은 불가능에 가깝다.
여기서 해싱은 복호화가 불가능한데 왜 해싱을 사용한지 의문이 듭니다.
해싱의 목적은 데이터 그 자체를 사용하는 것이 아니라, 동일한 값의 데이터를 사용했는지 여부만 확인하는 것이다.
예를 들어, 사이트 관리자가 해싱을 하지 않은 비밀번호를 관리하고 있다면 얼마든지 악용할 수 있다. 그래서 보통 비밀번호를 DB에 저장할 때, 원본 값을 알 수 없도록 해싱하여 저장한다. 해싱은 복호화가 불가능하므로 사이트 관리자도 정확한 비밀번호를 알 수 없게 된다.
비밀번호 찾기를 했을 때 기존의 비밀번호를 알려주지 않고 새로운 비밀번호를 입력하라고 하는 것이 이 때문이다. 사이트 관리자도 사용자의 비밀번호를 모르기 때문!
로그인 요청이 들어왔을 때 비밀번호를 해싱하여 DB에 저장된 비밀번호 해시값과 비교하여 값이 동일한지 체크하여 같다면 정확한 비밀번호를 입력했다고 판단할 수 있어 해싱을 이용해 로그인 처리를 할 수 있다.
세션기반 인증은 서버(혹은 DB)에 유저 정보를 담는 방식이고 사용자의 요청마다 DB를 확인해야 했다. 이 부담을 클라이언트에게 덜어낼 수 있도록 고안된 방식이 토큰기반 인증이다.
많은 웹 어플리케이션에서 사용하는 방식으로 JWT(JSON Web Token)을 사용한다.
JWT는 위 그림과 같이 .
으로 나누어진 세 부분이 있고 각각을 Header, Payload, Signature라고 부른다.
헤더는 이것이 어떤 종류의 토큰인지 어떤 알고리즘으로 시그니처를 암호화할지가 들어있다.
{
"alg": "HS256",
"typ": "JWT"
}
이 JSON 객체를 base64 방식으로 인코딩하면 헤더가 완성된다.
페이로드에는 단어 그대로 서버에서 활용할 수 있는 유저의 정보가 담겨 있다. 페이로드에 너무 민감한 정보는 담지 않는 것이 좋다. 왜냐하면 디코딩이 쉬운 base64 방식으로 인코딩되기 때문이다.
시그니처는 서버의 비밀키(암호화에 추가할 salt)와 헤더에서 지정한 알고리즘을 사용하여 해싱한다.