HTTPS

Creating the dots·2021년 9월 7일
0

HTTPS

목록 보기
1/2

HTTPS

Hyper Text Transfer Protocol Secure
HTTP요청을 SSL/TLS라는 알고리즘을 이용해 HTTP 통신을 하는 과정에서 내용을 암호화하여 데이터를 전송하는 방법

필요성

  • 기밀성(privacy): 메시지를 가로챌 수 없다 === 메시지를 읽을 수 없다 === 메시지가 암호화되어있다
  • 무결성(integrity): 메시지가 조작되지 않는다 <=== 암호화되어있기 때문에

*여기서 메시지는 요청, 응답 둘 다 의미

작동원리

CA와 인증서

  • CA(Certificate Authority)는 인증서를 발급해주는 기관
  • 각 브라우저는 각자 신뢰하는 CA의 정보를 가지고 있다
  • 발급된 인증서의 공개키는 브라우저, 개인키는 서버가 갖는다.
  • 브라우저는 서버에서 전송한 인증서와 응답을 보고, 인증서에 명시된 도메인과 응답객체의 도메인이 일치하는지를 확인해 접속한 서버가 "의도한" 서버임을 보장한다

비대칭 키 암호화: 암호화, 복호화하는 키가 다르다

  • 원리
    두개의 키가 하나의 쌍으로 존재하고, 하나로 암호화를 했다면 다른 하나로 복호화해야한다. 따라서 복호화하는 키는 비밀로 숨겨두고, 암호화하는 키는 클라이언트에 공개해서 데이터를 안전하게 전송한다.
    하지만, 클라이언트와 서버가 모든 통신을 비대칭키로 하면 서버에 부담이 되기 때문에, 인증서를 확인하는 과정에서 공개키를 사용하고, 이후 생성된 임시키(비밀키)로 대칭키 키 암호화를 사용한다.

  • 통신과정

    • hand shake
      • 클라이언트는 랜덤 데이터를 생성해서 서버에 보낸다
      • 서버도 랜덤 데이터를 생성해서 서버 인증서와 함께 클라이언트에 보낸다
    • 인증서 확인 (공개키)
      • CA의 인증을 받은 인증서들은 해당 CA의 개인키로 암호화되어있다
      • 따라서 브라우저에 저장된 CA 공개키로 서버에서 보낸 인증서 복호화한다
      • 성공적으로 복호화된 인증서에는 서버의 공개키가 포함되어 있다
    • 임시 키 생성
      • 클라이언트와 서버는 키 제작용 랜덤 스트링을 암호화하여 전송한다
      • 이렇게 교환된 임의의 정보를 바탕으로 임시 키가 생성된다
    • 상호 키 검증 (대칭키)
      • 클라이언트와 서버는 동일한 임시키로 각각 암호화된 메시지 전달한다
      • 클라이언트와 서버 모두 임시키로 메시지 복호화하고 다시 암호화하여 상대에게 전달한다
      • 클라이언트와 서버 모두 성공한다면, 성공적으로 키를 생성한 것이다

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

//Ubuntu mkcert 설치하기
$ 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/
  
//macOS 
$ brew install mkcert
# firefox를 사용할 경우 필요에 따라 설치해주세요.
$ brew install nss

//인증서 생성
//로컬을 인증된 발급기관으로 추가한다
$ mkcert -install

//localhost로 대표되는 로컬 환경에 대한 인증서를 만든다
$ mkcert -key-file key.pem -cert-file cert.pem localhost 127.0.0.1 ::1

//옵션으로 추가한 localhost, 127.0.0.1(IPv4), ::1(IPv6)에서 사용할 수 있는 인증서 완성. cert.pem, key.pem 이라는 파일이 생성된 것을 확인가능.
//key.pem의 경우 개인 키이므로 git에 커밋하지 않고, 암호처럼 다루어야 합니다.

//HTTP 서버작성
//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);

//서버실행 후 https://localhost:3001로 접속시 url 왼쪽에 자물쇠가 생긴 HTTPS 프로토콜 이용한다는 것을 알 수 있다
profile
어제보다 나은 오늘을 만드는 중

0개의 댓글