[TIL]201028 Authentication

Chaegyeom·2020년 10월 28일
0

TIL

목록 보기
57/77
post-thumbnail

인증(Authentication)

인증(Authentication)에는 세션(Session)과 암호화(Encryption)이 존재한다

보통 어떤 서비스를 만들어서 로컬환경에서 테스트 할 때는 서버 1개, 클라이언트도 1개인 경우가 많다

🤔서버는 어떻게 각 유저를 판별할까?

그런데 만약 만든 해당 서비스를 서비스하는 경우에(다른 사람들이 쓰는 경우) 하나의 서버에서 수많은 유저들을 어떻게 판별할 수 있을까?

대략 이런 상황이 발생하는 경우에 어떻게 서버는 각 유저를 판별할 수 있을까?

서버는

  • 세션(Session)
  • 쿠키(Cookie)
  • 토큰(Token)

을통해 각 유저를 판별하고 유저가 맞다면 꼬리표를 달아서 표시해 둔다

이 과정 중에 데이터를 주고 받는데 원본데이터로 주고받을 경우에 악의적인 사용자가 데이터를 가로챌 수 있을텐데 데이터 송수신간에 데이터를 어떻게 관리해야 할까?

암호화(Encryption)

암호화는 일련의 정보를 임의의 방식을 사용하여 다른 형태로 변환하여 해당 방식에 대한 정보를 소유한 사람을 제외하고 이해할 수 없도록 '알고리즘'을 이용해 정보를 관리하는 것이다 그리고 이런 암호화의 종류 중에는 해싱(Hashing)과 Salt가 있다.

🤔인증과정을 거치지 않는 경우에는 다음과 같은 문제가 생길 수 있다.


서버에 이메일을 요청하면 서버에서 해당 이메일에 관련된 response를 제공할 것이다
그러나 이렇게 설계했을 때는 보안상의 이슈가 발생할 수 있는데, 누구라도 이메일 정보만 알고 있으면 해당 이메일의 모든 부가정보에 접근할 수 있게 된다.

🤫그럼 비밀번호를 넣으면 되지 않을까? 비밀번호가 맞는지 비교해 보고 주면 되잖아?


이메일에 대한 정보와 패스워드를 같이 요청하면 서버에서의 요청을 데이터베이스에서 이메일과 패스워드 정보를 받아서 정보들을 비교해보는 과정을 거쳐서 정상적으로 맞는 경우에 데이터베이스에서 해당 이메일을 가지고 관련된 정보를 요청해서 반환을 해주는 과정을 따르게 된다.

이메일은 공개된 정보이고, 패스워드는 사용자가 관리하고 보안에 신경쓰는 수단인데 이것만으로 부족하다.
데이터베이스에 접근한 악의적인 사용자가 비밀번호를 알아내게 되면 비밀번호는 다른 사이트에서도 거의 유사하게 쓰기 때문에 해당 비밀번호를 가지고 다른 사이트에 대조해서 접근하게 되는 문제가 발생할 수 있다.

이런 비밀번호를 데이터베이스에 암호화해서 저장한다면 이런 문제를 예방할 수 있는데, 대표적으로 hashing과 salt가 있다.

해싱(Hashing)

Hashing이란 어떠한 문자열에 '임의의 연산'을 적용하여 다른 문자열로 변환하는 것이다.

  • 민감한 정보(비밀번호, 핸드폰 번호 등)를 그대로 노출 시키지 않고 한눈에 알아볼 수 없는 문자열로 변환하여 주고 받을 때 사용
  • 주로 Hashing은 서버 로직 내에서 이루어 지며 상대적으로 정보가 노출되기 쉬운 클라이언트 상에서의 보안을 신경쓰기 위해 사용

예를 들어 123456이라는 비밀번호가 대표적으로 쓰이는 해시함수인 SHA256을 통해 해싱이 되면 8D969EEF6ECAD3C29A3A629280E686CF0C3F5D5A86AFF3CA12020C923ADC6C92이라는 123456이라고는 알아볼 수도 없는 다른 문자열로 변환되게 된다 이렇게 비밀번호를 해싱해서 데이터베이스에 저장하는 경우 데이터베이스가 잘못되더라도 악용될 여지가 적다

해싱을 실직적으로 서비스에 적용할 때 지켜져야 할 대표적인 3가지!!

1. 모든 값에 대해 해시 값을 계산하는데 오래걸리지 않아야한다
로그인 할 때 마다 20초씩 걸리면 쓰기 힘들것이다!

2. 최대한 해시 값을 피해야하며, 모든 값은 고유한 해시 값을 가진다
해싱이 수학적 연산에 따라 문자데이터를 변환하는 것이기 때문에 극히 낮은 확률로 전혀 다른 문자열인데 동일한 해시값을 갖는 경우가 있을 것인데 이런경우가 있지 않도록(아예 없긴 힘들지만 하늘의 별따기 수준일 정도로!

3. 아주 작은 단위의 변경 이라도 완전히 다른 해시 값을 가져야 한다
'aaa' , 'aab'처럼 매우 적은 부분만 바뀐 상태여도 완전히 다른 해시값을 가져야 한다

😗그럼 비밀번호를 해싱해서 데이터베이스에 저장하고 해싱한 비밀번호가 맞는지 비교하자!


알고리즘을 알면 풀어낼 수 있는데 좀 더 안전하게 비밀번호를 보호할 수 없을까? 라는 생각이 들텐데 salt를 해싱과 더해서 더 안전하게 비밀번호를 보호할 수 있다.

Salt

해시 하려는 값(원본)에 추가하는 값이다.
해시함수는 아주 작은단위의 변경도 완전히 다른 해시값을 생성하기 때문에 원본 데이터에 내가 규정한 다른 값을 더한 후 해싱을 진행하게 되면 알고리즘을 알고있다고 해도 원본 데이터를 알 수 없게 된다.
123456을 SHA256으로 해싱하면 8D969EEF6ECAD3C29A3A629280E686CF0C3F5D5A86AFF3CA12020C923ADC6C92라는 값이 나오는데 이 때 123456에 내가 정한 salt값(여기에선 yong을 추가해봤다)을 추가해서 123456yong을 SHA256을 통해 해싱하면 F093F9F6DE940F56C354FC46B282C38CFDFDD8697FBB38B0F1B719871D052150와 같이 완전히 다른 해시값이 나오게 된다(간단하게 뒤에 추가해서 그렇지 사이에 넣거나 하면 더 알기 어려워진다)

1. 암호화를 진행했다면 '해당 알고리즘을 알고있는 순간' 바로 원본을 얻어낼 수 있다.
2. 원본값에 임의로 약속된 추가 문자열을 추가하여 해시를 진행하여 기존 해시값과 전혀 다른 해시 값이 반환되어 알고리즘이 노출 되더라도 원본 값을 보호할 수 있도록 하는 안전장치이다.
3. 기존 : (암호화 하려는 값) => (hash값)
Salt 사용 : (암호화 하려는 값) + (Salt 용 값) => (hash값)

😆해싱에 salt까지 적용해서 더 안전하게 비밀번호를 보관하자!

쿠키(Cookie)와 세션(Session) 그리고 토큰(Token)을 통해 서버에서 유저를 판별할 수 있다고 했는데 쿠키와 세션, 토큰은 뭘까?

쿠키(Cookie)

쿠키(Cookie)란 서버가 사용자의 위치에 정보를 저장하고 불러올 수 있는 수단이다.

  1. 특정 호스트에서 생성된 쿠키는 이후 모든 요청마다 서버로 다시 전송된다
    브라우저가 서버랑 연결됐을 때, 서버측에서 해당쿠기가 존재하지 않을 경우에 자동적으로 쿠기를 생성해서 어떤 데이터를 response할 때 쿠기를 담아서 보낸다. 그 이후에 클라이언트가 서버에 요청을 보낼 때마다 어떤 액션을 취하지 않더라도 http요청에 담겨서 요청이 된다.
  2. 이름, 값, 만료 날짜, 경로 정보로 구성되어 있다.
  3. 크롬 개발자도구의 네트워크탭에 header부분에서 쿠키를 확인할 수 있다.


클라이언트가 서버로 리퀘스트를 보내면 서버가 set-cookie를 통해 자동적으로 생성된 데이터나 임의의 데이터를 키-값 형태로 담아서 리스폰스로 보내준다 그 이후에 클라이언트가 쿠키를 지우기 전까지 아무것도 하지 않아도 자동적으로 해당 클라이언트에서 해당 서버로 데이터를 보낼 때 유지되면서 송수신 하는 것

쿠키는 클라이언트 측에서 관리가 된다(서버와 클라이언트가 대화하기 위한 수단이라고 할 수 있다.)

세션(Session)

서버와 클라이언트의 연결이 활성화 된 상태

  1. 서버가 Client에 대해 유일한 ID를 부여하여 서버 측에서 관리
  2. 일반적으로 이 유일한 Client ID가 서버에서 존재하는 상황을 Session이라고 칭한다
    (브라우저와 서버가 연결되어 있을 때, 그 때만 존재한다)
  3. 각 Client ID의 Session 객체 마다 Data를 관리 할 수 있음
  4. 사용자의 정보 중 보안상 중요한 데이터는 Session에서 관리한다

토큰(Token)

인증을 위해 사용되는 암호화 된 문자열

  1. Http 통신의 Stateless 특징과 알맞다
    기본적으로 http통신은 열결된 상태일 때만 정보를 교류할 수 있게 되어 있고, 서버와 열결이 되어있지 않은 상태에서는 정보를 넘길 수 없고 정보를파기한다. 토큰을 가지고 있는 경우 상태에 연연하지 않고 판단을 내릴 수 있다. 어떤 유저에 대해서 상태를 관리할 필요가 없기 때문에 stateless라고 한다
  2. 유저의 인증 정보를 서버나 세션에 담아두지 않는다
    토큰에 대해서 판별을 할 수 있기 때문에 세션을 생성해서 브라우저 정보를 담아주지 않아도 판단을 할 수 있는 지표가 된다
  3. 유저의 활성화 여부를 신경쓰지 않고 넘겨진 요청에 담겨진 Token의 정합성만을 확인한다
    연결되어있는지 아닌지에 대해서 신경쓰지 않고 토큰이 정상적인지만 확인하고 진행을 한다
  4. 서버에서 클라이언트의 상태 정보를 저장하지 않고 클라이언트에서 넘겨지는 요청만으로 작업을 처리하게 되는데 이런 경우 클라이언트 상태관리에 관한 비용이 없기 때문에 서버의 확장성이 높다

토큰을 통해 짜는 경우 로직에 관해서만 짜고 미들웨어에서 토큰을 확인하기만 하면 되기 때문에 세션을 관리할 필요가 적어진다

profile
주니어 개발자가 되고싶은

0개의 댓글