[웹 인증 / 보안] HTTPS / Hashing / Cookie

young·2022년 7월 14일
0

6/23~7/20 Section 3 TIL

목록 보기
17/21

✅ TIL

  • HTTPS 프로토콜
    TLS
    로컬 환경에서 인증서를 생성하고 HTTPS 서버 만들기 실습
  • Hashing: 문자열 ->임의의 연산 -> 다른 문자열로 변환하는 것
    salt: 별도의 값

  • Cookie: 서버가 클라이언트에 특정한 정보를 저장
    (Session: 서버에 저장)


웹 인증 / 보안

1️⃣ HTTPS 프로토콜

Hyper Text Transfer Protocol Secure Socket layer
HTTP over SSL(TLS) / HTTP over Secure이라고 부르기도 한다.

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

  • HTTP: 클라이언트 요청의 내용을 그대로 볼 수 있다.
    HTTPS: HTTP 프로토콜 내용을 암호화 HTTP + Secure (보안기능)

클라이언트는 plaintext를 서버에 전송한다.
서버에서는 암호화 알고리즘을 가지고, 데이터를 암호화하여 DB와 저장 또는 대조한다.
DB는 암호화된 데이터를 갖는다.


암호화

제 3자가 서버와 클라이언트가 주고받는 정보를 탈취할 수 없도록 하는 것이다.
암호화된 정보는 정확한 키로 복호화하기 전까지 어떤 내용인지 알 수 없다.
비대칭키 방식과 대칭키 방식을 혼용하여 사용한다.


인증서

서버의 신원을 보증하여, 사용자에게 접속한 브라우저가 안전함을 보장해주는 역할을 한다.

  1. 서버는 클라이언트에게 CA에서 발급받은 인증서와 함께 응답객체를 전송한다.
  2. 클라이언트는 인증서의 도메인과 서버의 도메인을 비교한다.
  3. 클라이언트에서 확인한 인증서가 인증된 CA에서 발급한 인증서가 아니라면 화면에 경고창을 띄워 서버와 연결이 안전하지 않음을 알린다.
  4. 인증서가 확인되면 브라우저에 제공된 해당 CA 기관의 공개키로 서버 인증서를 복호화한다.

인증서가 CA의 비밀키로 암호화되어 있기 때문에 CA의 개인키로 복호화 가능하다. 따라서 해당 CA에서 발급한 인증서라는 것을 보증할 수 있다.


CA

Certificate Authority
인증서를 발급하는 공인된 기관

브라우저마다 각각의 CA 공개키를 가진다.
서버의 공개키와 정보를 CA의 비밀키로 암호화하여 인증서를 발급한다.

브라우저는 인증서의 도메인과 서버의 도메인을 비교함으로 보안 위협으로부터 사용자 및 사용자의 데이터를 보호하고, 화면에 경고창을 보여줌으로써 안전한 서버를 사용자가 사용하도록 유도한다.

서버와 클라이언트간의 CA를 통해 서버를 인증하는 과정과 데이터를 암호화하는 과정을 아우른 프로토콜을 TLS 또는 SSL이라고 한다.
(SSL이 표준화되면서 바뀐 이름이 TLS이다.)




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

  1. mkcert 설치
    로컬 환경에서 신뢰할 수 있는 인증서를 만든다.
$ brew install mkcert
  1. 인증서 생성
//1. 로컬을 인증된 발급기관으로 추가한다
$ mkcert -install

//2. localhost, 127.0.0.1, ::1(IPv6)에서 사용할 수 있는 인증서를 만든다.
$ mkcert -key-file key.pem -cert-file cert.pem localhost 127.0.0.1 ::1

key.pem: 키 파일
cert.pem: 인증서

  1. Node.js 환경에서 https 모듈을 이용한 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);
  1. 서버 실행하기

    localhost:3001에서 HTTPS 프로토콜을 이용한다는 것을 볼 수 있다




2️⃣ Hashing

어떤 문자열에 임의의 연산(SHA1, SHA256 등의 알고리즘)을 적용하여 다른 문자열로 변환하는 것

  1. 모든 값에 대해 해시 값을 계산하는 데 오래걸리지 않아야 한다.
  2. 최대한 해시 값을 피해야 하며, 모든 값은 고유한 해시값을 가진다.
  3. 아주 작은 단위의 변경이라도 완전히 다른 해시 값을 가져야 한다.

Salt

암호화해야 하는 값에 어떤 별도의 값을 추가하여 결과를 변형하는 것
알고리즘이 노출되더라도 원본값을 보호할 수 있도록 하는 안전장치이다.

유저와 패스워드 별로 유일한 값을 가져야 한다.
계정을 생성할 때, 패스워드를 변경할 때마다 임의의 salt를 사용해서 해싱해야 한다.
절대 재사용하지 말아야 한다.
DB의 유저 테이블에 같이 저장되어야 한다.





어떤 웹사이트에 들어갔을 때, 서버가 일방적으로 클라이언트에 전달하는 작은 데이터
해당 도메인에 대해 쿠키가 존재하면, 브라우저는 서버에 HTTP 요청시 쿠키를 함께 전달한다.

  • 서버가 웹 브라우저에 정보를 저장하고 불러올 수 있는 수단이다.
  • 직접 삭제하지 않으면 사라지지 않으므로 장시간 보존해야 하는 정보 저장에 적합하다.
  • 민감한 정보나 개인 정보, 인증에 관련된 정보는 포함하지 않는 것이 좋다.

즉, 쿠키는 오랜 시간 유지될 수 있으며, 경우에 따라 자바스크립트로 쿠키에 접근할 수 있기 때문에 쿠키에 민감한 정보를 담는 것은 위험하다.

//쿠키 생성
res.cookie(,, 옵션)

//쿠키 삭제
//쿠키를 삭제하려면 쿠키를 저장할 때의 키, 값, 쿠키 옵션이 모두 일치해야 삭제할 수 있다.
//expires, maxAge는 일치할 필요 x
res.clearCookie(,, 옵션)

Set-Cookie: 서버에서 쿠키 옵션을 지정하고 클라이언트에 전송할 때 사용
Cookie : 클라이언트에서 서버로 쿠키를 전송할 때 사용


쿠키 옵션

1. Domain

www.google.com과 같은 서버에 접속할 수 있는 이름
쿠키 옵션에서 포트 및 서브 도메인 정보(www 등), 세부 경로를 포함하지 않는다.

클라이언트에서는 쿠키의 도메인 옵션과 서버의 도메인이 일치해야만 쿠키를 전송할 수 있다.

2. Path

세부 경로 = 서버가 라우팅할 때 사용하는 경로
명시하지 않으면 기본값 /
Path 옵션에 설정된 경로를 포함하는 하위 경로로 요청하면 쿠키를 서버에 전송할 수 있다.
(Path가 /users로 설정되어 있고, /users/page면 쿠키 전송 가능)

3. maxAge or Expires

쿠키의 유효 시간 설정

maxAge: 초 단위로 유효 시간을 설정한다.
Expires: 클라이언트의 시간을 기준으로, 유효 기한 날짜와 시간을 지정한다. 지정된 날짜와 시간을 초과하면 쿠키는 자동으로 파괴된다.

  • 세션 쿠키: maxAge 또는 Expires 옵션이 없는 쿠키, 브라우저를 종료하면 삭제된다.
  • 영속성 쿠키: maxAge 또는 Expires에 지정된 유효시간만큼 사용 가능한 쿠키

4. Secure

true일 경우 HTTPS 프로토콜에서만 쿠키를 전송할 수 있다.
Secure 옵션이 없다면 프로토콜에 관계 없이 쿠키를 전송할 수 있다.

5. HttpOnly

자바스크립트에서 브라우저의 쿠키에 접근 허용 여부
명시되지 않으면 기본값 false
true인 경우 접근 불가, false인 경우 script 태그로 접근 가능하다. ➞ XSS 공격에 취약

6. SameSite

Cross-Origin 요청을 받은 경우 요청에서 사용한 메소드와 해당 옵션에 따른 서버의 쿠키 전송 여부를 정할 수 있다.
CSRF 공격을 방지할 수 있다.

  • Lax: Cross-Origin 요청이라면 GET 메소드에 대해서만 쿠키를 전송할 수 있다.

  • Strict: 가장 엄격한 옵션. Cross-Origin이 아닌 same-site인 경우에만 쿠키를 전송할 수 있다.

    • same-site: 요청을 보낸 Origin과 서버의 도메인, 프로토콜, 포트가 같은 경우, 하나라도 다르면 Cross-Origin으로 구분된다.
  • None: 항상 쿠키를 보내줄 수 있다. ➞ Secure 옵션 필요



쿠키를 이용한 상태 유지

서버는 클라이언트에 인증 정보를 담은 쿠키를 전송한다.
클라이언트는 전달받은 쿠키를 서버에 요청과 같이 전송한다.
따라서 Stateless한 인터넷 연결을 Stateful하게 유지할 수 있게 된다.




Learn more...

ngrok: HTTP로 만들어진 서버를 HTTPS 프로토콜로 터널링해주는 프로그램

profile
즐겁게 공부하고 꾸준히 기록하는 나의 프론트엔드 공부일지

0개의 댓글