인증(Authentication)에는 세션(Session)과 암호화(Encryption)이 존재한다
보통 어떤 서비스를 만들어서 로컬환경에서 테스트 할 때는 서버 1개, 클라이언트도 1개인 경우가 많다
그런데 만약 만든 해당 서비스를 서비스하는 경우에(다른 사람들이 쓰는 경우) 하나의 서버에서 수많은 유저들을 어떻게 판별할 수 있을까?
대략 이런 상황이 발생하는 경우에 어떻게 서버는 각 유저를 판별할 수 있을까?
서버는
을통해 각 유저를 판별하고 유저가 맞다면 꼬리표를 달아서 표시해 둔다
이 과정 중에 데이터를 주고 받는데 원본데이터로 주고받을 경우에 악의적인 사용자가 데이터를 가로챌 수 있을텐데 데이터 송수신간에 데이터를 어떻게 관리해야 할까?
암호화는 일련의 정보를 임의의 방식을 사용하여 다른 형태로 변환하여 해당 방식에 대한 정보를 소유한 사람을 제외하고 이해할 수 없도록 '알고리즘'을 이용해 정보를 관리하는 것이다 그리고 이런 암호화의 종류 중에는 해싱(Hashing)과 Salt가 있다.
서버에 이메일을 요청하면 서버에서 해당 이메일에 관련된 response를 제공할 것이다
그러나 이렇게 설계했을 때는 보안상의 이슈가 발생할 수 있는데, 누구라도 이메일 정보만 알고 있으면 해당 이메일의 모든 부가정보에 접근할 수 있게 된다.
이메일에 대한 정보와 패스워드를 같이 요청하면 서버에서의 요청을 데이터베이스에서 이메일과 패스워드 정보를 받아서 정보들을 비교해보는 과정을 거쳐서 정상적으로 맞는 경우에 데이터베이스에서 해당 이메일을 가지고 관련된 정보를 요청해서 반환을 해주는 과정을 따르게 된다.
이메일은 공개된 정보이고, 패스워드는 사용자가 관리하고 보안에 신경쓰는 수단인데 이것만으로 부족하다.
데이터베이스에 접근한 악의적인 사용자가 비밀번호를 알아내게 되면 비밀번호는 다른 사이트에서도 거의 유사하게 쓰기 때문에 해당 비밀번호를 가지고 다른 사이트에 대조해서 접근하게 되는 문제가 발생할 수 있다.
이런 비밀번호를 데이터베이스에 암호화해서 저장한다면 이런 문제를 예방할 수 있는데, 대표적으로 hashing과 salt가 있다.
Hashing이란 어떠한 문자열에 '임의의 연산'을 적용하여 다른 문자열로 변환하는 것이다.
예를 들어 123456
이라는 비밀번호가 대표적으로 쓰이는 해시함수인 SHA256을 통해 해싱이 되면 8D969EEF6ECAD3C29A3A629280E686CF0C3F5D5A86AFF3CA12020C923ADC6C92
이라는 123456이라고는 알아볼 수도 없는 다른 문자열로 변환되게 된다 이렇게 비밀번호를 해싱해서 데이터베이스에 저장하는 경우 데이터베이스가 잘못되더라도 악용될 여지가 적다
1. 모든 값에 대해 해시 값을 계산하는데 오래걸리지 않아야한다
로그인 할 때 마다 20초씩 걸리면 쓰기 힘들것이다!
2. 최대한 해시 값을 피해야하며, 모든 값은 고유한 해시 값을 가진다
해싱이 수학적 연산에 따라 문자데이터를 변환하는 것이기 때문에 극히 낮은 확률로 전혀 다른 문자열인데 동일한 해시값을 갖는 경우가 있을 것인데 이런경우가 있지 않도록(아예 없긴 힘들지만 하늘의 별따기 수준일 정도로!
3. 아주 작은 단위의 변경 이라도 완전히 다른 해시 값을 가져야 한다
'aaa' , 'aab'처럼 매우 적은 부분만 바뀐 상태여도 완전히 다른 해시값을 가져야 한다
알고리즘을 알면 풀어낼 수 있는데 좀 더 안전하게 비밀번호를 보호할 수 없을까? 라는 생각이 들텐데 salt를 해싱과 더해서 더 안전하게 비밀번호를 보호할 수 있다.
해시 하려는 값(원본)에 추가하는 값이다.
해시함수는 아주 작은단위의 변경도 완전히 다른 해시값을 생성하기 때문에 원본 데이터에 내가 규정한 다른 값을 더한 후 해싱을 진행하게 되면 알고리즘을 알고있다고 해도 원본 데이터를 알 수 없게 된다.
123456
을 SHA256으로 해싱하면 8D969EEF6ECAD3C29A3A629280E686CF0C3F5D5A86AFF3CA12020C923ADC6C92
라는 값이 나오는데 이 때 123456
에 내가 정한 salt값(여기에선 yong
을 추가해봤다)을 추가해서 123456yong
을 SHA256을 통해 해싱하면 F093F9F6DE940F56C354FC46B282C38CFDFDD8697FBB38B0F1B719871D052150
와 같이 완전히 다른 해시값이 나오게 된다(간단하게 뒤에 추가해서 그렇지 사이에 넣거나 하면 더 알기 어려워진다)
1. 암호화를 진행했다면 '해당 알고리즘을 알고있는 순간' 바로 원본을 얻어낼 수 있다.
2. 원본값에 임의로 약속된 추가 문자열을 추가하여 해시를 진행하여 기존 해시값과 전혀 다른 해시 값이 반환되어 알고리즘이 노출 되더라도 원본 값을 보호할 수 있도록 하는 안전장치이다.
3. 기존 : (암호화 하려는 값) => (hash값)
Salt 사용 : (암호화 하려는 값) + (Salt 용 값) => (hash값)
쿠키(Cookie)와 세션(Session) 그리고 토큰(Token)을 통해 서버에서 유저를 판별할 수 있다고 했는데 쿠키와 세션, 토큰은 뭘까?
쿠키(Cookie)란 서버가 사용자의 위치에 정보를 저장하고 불러올 수 있는 수단이다.
클라이언트가 서버로 리퀘스트를 보내면 서버가 set-cookie를 통해 자동적으로 생성된 데이터나 임의의 데이터를 키-값 형태로 담아서 리스폰스로 보내준다 그 이후에 클라이언트가 쿠키를 지우기 전까지 아무것도 하지 않아도 자동적으로 해당 클라이언트에서 해당 서버로 데이터를 보낼 때 유지되면서 송수신 하는 것
쿠키는 클라이언트 측에서 관리가 된다(서버와 클라이언트가 대화하기 위한 수단이라고 할 수 있다.)
서버와 클라이언트의 연결이 활성화 된 상태
인증을 위해 사용되는 암호화 된 문자열
토큰을 통해 짜는 경우 로직에 관해서만 짜고 미들웨어에서 토큰을 확인하기만 하면 되기 때문에 세션을 관리할 필요가 적어진다