[인증/보안] 기초

Jelkov Ahn·2021년 12월 27일
0

인증/보안

목록 보기
1/4
post-thumbnail

Achievement Goals

  • 암호화와 hashing, salting 등의 개념을 이해할 수 있다.
  • HTTP와 HTTPS의 차이점을 이해할 수 있다.
  • 권한 부여(Authorization)와 인증(Authentication)에 대해 이해할 수 있다.
  • 쿠키의 작동 원리를 이해할 수 있다
  • 세션 및 쿠키 / 토큰 / OAuth를 통해 인증 구현을 할 수 있다.
  • 클라이언트, 서버, 데이터베이스의 전체 동작을 이해할 수 있다.
  • 회원가입 및 로그인 등의 유저 인증에 대해 구현하고 이해한다.
  • 서비스의 보안과 관련된 방법을 알아보고 원리 및 장점 및 단점을 이해한다.

HTTPS(Hyper Text Transfer Protocol Secure Socket layer) 프로토콜

HTTPS는 HTTP 요청을 SSL 혹은 TLS라는 알고리즘을 이용해, HTTP 통신을 하는 과정에서 내용을 암호화하여 데이터를 전송하는 방법입니다.

인증에서 HTTPS 프로토콜을 사용해야만 하는 이유는 HTTP보다 상대적으로 안전한 방법이고, 데이터 제공자의 신원을 보장받을 수 있기 때문입니다.

질문: SSL, TLS는 무엇인가요? SSL과 인증기관(CA)은 어떤 관계가 있나요?

-> SSL (보안 소켓 레이어) 그리고 그 후계자 TLS (전송 계층 보안)는 네트워크로 연결된 컴퓨터간에 인증되고 암호화 된 링크를 설정하기위한 프로토콜입니다.

-> SSL 인증서 (일컬어 TLS 또는 SSL /TLS 인증서)는 웹 사이트의 ID를 공개 키와 개인 키로 구성된 암호화 키 쌍에 바인딩하는 디지털 문서입니다. 인증서에 포함 된 공개 키를 사용하면 웹 브라우저에서 시작 웹 서버와의 암호화 된 통신 세션 TLS 및 HTTPS 프로토콜. 개인 키는 서버에 안전하게 보관되며 웹 페이지 및 기타 문서 (예 : 이미지 및 JavaScript 파일)에 디지털 서명하는 데 사용됩니다.

암호화 작업

HTTPS 프로토콜의 특징 중 하나는 암호화된 데이터를 주고받기 때문에, 중간에 인터넷 요청이 탈취되더라도 그 내용을 알아볼 수 없습니다.

데이터 제공자의 신원을 확인하고 보장받는 게 인증에서 중요한 이유는 다음과 같습니다.

클라이언트는 데이터 제공자가 제공해 준 데이터를 사용할 수밖에 없습니다.
클라이언트는 서버에 데이터 요청을 하고 이후 받은 데이터를 이용해서 화면을 렌더링하는 등의 작업을 해야 합니다.

그렇기 때문에 요청 및 응답을 중간에서 가로채는 중간자 공격 Man-in-the-middle attack 에 취약합니다.
따라서 해당 데이터를 암호화시키는 작업이 필요합니다.

그래서 암호화는 일련의 정보를 임의의 방식을 사용하여 다른 형태로 변환하여 해당방식에 대한 정보를 소유한 사람을 제외하고 이해할 수없도록 '알고리즘'을 이용해 정보를 관리하는 과정입니다.

인증서
HTTPS 프로토콜의 또 다른 특징 중 하나는 브라우저가 응답과 함께 전달된 인증서 정보를 확인할 수 있다는 점입니다.
브라우저는 인증서에서 해당 인증서를 발급한 CA 정보를 확인하고 인증된 CA가 발급한 인증서가 아니라면 아래와 같이 화면에 경고창을 띄워 서버와 연결이 안전하지 않다는 화면을 보여줍니다.

사설 인증서 발급 및 HTTPS 서버 구현


mkcert라는 프로그램을 이용해서 로컬 환경(내 컴퓨터)에서 신뢰할 수 있는 인증서를 만들 수 있습니다.

Ubuntu

$ sudo apt install libnss3-tools
$ wget -O mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.3/mkcert-v1.4.3-linux-amd64
$ chmod +x mkcert
$ sudo cp mkcert /usr/local/bin/

인증서 생성

$ mkcert -install // 로컬을 인증된 발급기관으로 추가해야 합니다.
$ mkcert -key-file key.pem -cert-file cert.pem localhost 127.0.0.1 ::1 // localhost로 대표되는 로컬 환경에 대한 인증서를 만들려면 다음 명령어를 입력해야 합니다.

cert.pem, key.pem 이라는 파일이 생성

HTTPS 서버 작성

Node.js https 모듈 이용

const https = require('https');
const fs = require('fs');

https
  .createServer(
    {
      key: fs.readFileSync(__dirname + '/key.pem', 'utf-8'),
      cert: fs.readFileSync(__dirname + '/cert.pem', 'utf-8'),
    },
    function (req, res) {
      res.write('Congrats! You made https server now :)');
      res.end();
    }
  )
  .listen(3001);

express.js 이용

const https = require('https');
const fs = require('fs');
const express = require('express');

const app = express();

https
  .createServer(
    {
      key: fs.readFileSync(__dirname + '/key.pem', 'utf-8'),
      cert: fs.readFileSync(__dirname + '/cert.pem', 'utf-8'),
    },
    app.use('/', (req, res) => {
      res.send('Congrats! You made https server now :)');
    })
  )
  .listen(3001);

HASHING

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

  1. 모든 값에 대해 해시 값을 계산하는데 오래걸리지 않아야 한다.

  2. 최대한 해시 값을 피해야하며, 모든 값은 고유한 해시 값을 가진다.

  3. 아주 작은 단위의 변경이라도 완전히 다른 해시 값을 가져야 한다.

SALT

암호화해야 하는 값에 어떤 '별도의 값'을 추가하여 결과를 변형하는 것

  1. 암호화만 해놓는다면 해시된 결과가 늘 동일
    해시된 값과 원래 값을 테이블로 만들어서 decoding 해버리는 경우도 생긴다. ( 역으로 추적)

  2. 원본값에 임의로 약속된 ' 별도의 문자열'을 추가하여 해시를 진행한다면, 기존 해시값과 전혀 다른 해시 값이 반환되어 알고리즘이 노출되더라도 원본값을 보호할 수 있도록 하는 안전 장치

  3. 기존 (암호화하려는 값) => (hash 값)
    salt사용 (암호화하려는 값)+(salt용 값) =>(hash 값)

사용시 주의해야 할점

  1. salt는 유저와 패스워드 별로 유일한 값을 가져야 합니다.

  2. 사용자 계정을 생성할 때와 비밀번호를 변경할 때마다, 새로운 임의의 salt를 사용해서 해싱해야 합니다.

  3. salt는 절대 재사용하지 말아야 합니다.

  4. salt는 db의 유저테이블에 같이 저장되어야 합니다.

profile
끝까지 ... 가면 된다.

0개의 댓글