HTTPS는 HTTP 프로토콜의 내용을 암호화하여 보완성을 추가했다. 기존 HTTP는 누군가 요청의 내용을 들여다보려 한다면 그대로 볼 수가 있었다. 그렇게 되면 중요한 정보가 쉽게 노출될 수 있을 것이다.
하지만 HTTPS는 요청의 내용을 암호화하기 때문에 정보가 유출되더라도 정확한 키가 없다면 어떤 내용인지 알 수 없고 데이터 제공자의 신원을 보장받을 수 있다.
데이터 제공자의 신원을 보장받는 게 인증에서 중요한 이유
CA (Certificate Authority)
비대칭 키 암호화 (공개키 암호화)
키 A로 암호화 => 키 B로만 복호화 가능 !
Hand Shake 에서는 서로를 확인하고 서버는 클라이언트의 공개키 한 쌍 중 하나를 전달.
클라이언트는 전달받은 키를 이용해서 서버와 키를 만들어낼 임의의 정보를 암호화해서 전달
서버는 클라이언트와 마찬가지로 임의의 정보를 암호화해서 전달
클라이언트와 서버는 서로 만들고 교환한 임의의 정보를 바탕으로 비밀 키 생성
각자 생성한 키를 바탕으로 클라이언트가 텍스트용 데이터를 만들어낸 비밀키로 암호화를 해서 전달
서버 역시 만들어진 비밀키로 복호화를 하고 다시 암호화해서 클라이언트로 전달
클라이언트가 같은 내용의 데이터를 복호화하는데 성공한다면 성공적으로 비밀키가 만들어진 상태. (HTTPS 연결 성립)
mkcert
라는 프로그램을 이용하여 로컬 환경에서 신뢰할 수 있는 인증서 발급 가능.
Ubuntu
$ sudo apt install libnss3-tools
$ wget -0 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
$brew install nss
인증서 생성
$ mkcert -install
로컬을 인증된 발급기관으로 추가
$ mkcert -key-file key.pem -cert-file cert.pem localhost 127.0.0.1 ::1
로컬 환경에 대한 인증서 만들기
=> cert.pem
, key.pem
파일 생김.
(key.pem의 경우 개인 키이므로 git에 커밋하지 않고 암호처럼 다룸)
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);
일련의 정보를 임의의 방식을 사용하여 다른 형태로 변환하여 해당 방식에 대한 정보를 소유한 사람을 제외하고 이해할 수 없도록 '알고리즘'을 이용해 정보를 관리하는 과정
어떠한 문자열에 '임의의 연산'을 적용하여 다른 문자열로 변환하는 것
철칙
1. 모든 값에 대해 해시 값을 계산하는데 오래 걸리지 않아야 한다.
2. 최대한 해시 값을 피해햐 하며, 모든 값은 고유한 해시 값을 가진다.
3. 아주 작은 단위의 변경이라도 완전히 다른 해시 값을 가져야 한다.
암호화해야 하는 값에 어떤 '별도의 값'을 추가하여 결과를 변형하는 것
Salt 사용 시 주의점
1. Salt는 유저와 패스워드 별로 유일한 값을 가져야 함
2. 사용자 계정을 생성할 때와 비밀번호를 변경할 때마다 새로운 임의의 Salt를 사용해서 해싱해야 함
3. 재사용하면 절대 안 됨.
4. DB의 유저 테이블에 같이 저장되어야 함.
HTTP는 stateless인데 어떻게 정보가 유지되는가? => 쿠키
어떤 웹사이트에 들어갔을 때, 서버가 일방적으로 클라이언트에 전달하는 작은 데이터
이러한 쿠키의 특성을 이용하여 서버는 클라이언트에 인증정보를 담은 쿠키를 전송하고, 클라이언트는 전달받은 쿠키를 요청과 같이 전송하여 Stateless한 인터넷 연결을 Stateful하게 유지할 수 있다.
하지만 쿠키는 오랜 시간 유지될 수 있고, JS를 통해 접근 가능하기 때문에 쿠키에 민감 정보를 담는 것은 위험
쿠키 전달 방법
쿠키 옵션