HTTPS


HTTPS


Hyper Text Transfer Protocol Secure
HTTP要求SSL/TLSというアルゴリズムを用いてHTTP通信を行う場合、どのようにコンテンツを暗号化してデータを伝送するか.

必要性

  • 機密性(プライバシー):メッセージをブロックできない==メッセージを読み取ることができない==メッセージが暗号化された
  • 整合性(integrity):メッセージが暗号化されていないため、
  • *このメッセージは、要求と応答を表します.

    さぎょうげんり


    CAと証明書

  • CA(Certificate Authority)は、証明書を発行する機関
  • である.
  • 各ブラウザには、信頼できるCA情報
  • があります.
  • によって発行された証明書の公開鍵はブラウザによって、秘密鍵はサーバによって所有される.
  • ブラウザは、サーバから送信された証明書と応答を表示し、証明書に示されているドメインと応答オブジェクトのドメインが一致していることを確認して、接続されているサーバが「予期された」サーバであることを確認します.

    非対称鍵暗号化:暗号化、復号化の鍵が異なる


  • n/a原理
    2つの鍵がペアとして存在し、1つで暗号化されている場合は、別の鍵で復号する必要があります.したがって、復号鍵は秘密にされ、暗号鍵はクライアントに公開され、データが安全に伝送される.ただし、クライアントとサーバのすべての通信が非対称鍵である場合、サーバに負担がかかるため、証明書の検証中に公開鍵を使用し、生成された一時鍵(秘密鍵)を使用して対称鍵を暗号化します.

  • つうしんプロセス
  • 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 프로토콜 이용한다는 것을 알 수 있다