[포스코 x 코딩온] 웹 풀스택 8주차 회고 -1

sima·2023년 8월 27일
0

KDT web-8

목록 보기
10/17
post-thumbnail

JWT(JSON Web Token)

웹 애플리케이션에서 정보를 안전하게 전송하기 위한 방법
인증된 사용자 식별, 데이터 서명하여 변조 방지

JWT 구성

Header - 토큰의 타입과 해시 알고리즘 정보
Payload - 실제 정보를 가진 데이터, claim이라 불리는 Key-Value로 이루어져 있음
Signature - 토큰의 무결성 검증위한 서명 부분, Header와 Payload의 조합에 비밀 키 사용해 생성

JWT 작동 방식

Client/사용자 가 로그인을 시도 → Server에서 로그인 정보 확인 후, JWT 생성하여 Client 에게 JWT와 같이 응답 → 이후 Client 에서 데이터를 요청할 때, 발급받은 JWT를 헤더에 담아 요청 → Server에서 받은 요청에서 JWT 검증을 수행한 후, 데이터 응답

Node에서 JWT 사용

npm install jsonwebtoken

→ jsonwebtoken 모듈 설치

import jwt from 'jsonwebtoken';

const SECRETKEY = 'abcdefghijklmnopqrstuvwxyz1234567890';

//토큰 생성
jwt.sign({ id : userid }, SECRETKEY);
//sign(payload, secretOrPrivateKey, [options, callback])

//토큰 검증
//1. 헤더에서 토큰값 추출
const auth = req.headers.authorization;
const token = auth.split(' ')[1];

//2. JWT 검증
jwt.verify(token, SECRETKEY, (err, encoded)=> {
	...
});
// verify(token, secretOrPrivateKey, [options, callback]);




암호화

단방향 암호화

  • 단방향이므로 복호화 불가능
  • 동일한 데이터에 대해서는 항상 같은 해시값이 생성됨(다른 데이터도 충돌이 나 같은 해시값이 나올수도 있음)
  • 데이터 무결성 검증에 사용, 해시함수(MD5, SHA)를 사용하여 구현

해시함수

  • 임의의 크기의 데이터를 고정된 크기의 데이터로 변환하는 함수
  • Key - 매핑 전 원래 데이터 값, Value - 매핑 후 데이터값
  • 가장 많이 사용하는 알고리즘은 SHA-256, SHA-512 사용

양방향 암호화

  • 양방향이므로 복호화 가능
  • 데이터 기밀성 유지, 안전한 통신 위해 사용
  • 공개키, 대칭키 암호화를 조합하여 보안 유지, 처리속도 향상
  • 프로토콜로 클라이언트-서버 통신을 보호

대칭키 암호화 알고리즘

  • AES
    • 다양한 키, 블록 제공
    • 빠른 처리속도, 다양한 플랫폼 구현가능
    • 다양한 운용모드 통해 데이터 블록 처리
    • AES-128, AES-192, AES-256
  • RSA, ECC
    • 공개키, 개인키 두개의 키 쌍을 이용
    • 공개키는 다른사람과 공유, 개인키는 오직 소유자만 알고 있어야 함
    • ECC는 작은 키 길이로도 강력한 보안 제공, RSA는 대칭키 암호화보다 복잡하지만 효율적으로 사용

Node에서의 암호화 모듈 (1) - CryptoJS

CryptoJS 사용 예시(단방향 암호화)

import crypto from 'crypto';

const createHashedPassword = (password) => {
		//				알고리즘			암호화할 값			인코딩 방식
	return crypto.createHash(algorithm).update(password).digest(encoding);
}

const salt = crypto.randomBytes(16).toString('base64'); //솔트값
const iterations = 10000; //반복 횟수
const keylen = 64;  //생성할 키 길이
const digest = 'sha512';  //알고리즘

//비밀번호 기반 키 도출함수
const createPbkdf = (password) => {
	return crypto.pbkdf2Sync(password, salt, iterations, keylen, digest).toString('base64');
};

//검증
const verifyPassword = (password, salt, dbPassword) => {
	const compare = crypto.pbkdf2Sync(password, salt, iterations, keylen, digest).toString('base64');
    
    if(compare === dpPassword) return true;
    return false;
};

createHash(algorithm) - 해시알고리즘 사용해 해시 객체 생성
pdkdf2Sync(pw, salt, iterations, keylen, digest) - 비밀번호 기반 키 도출 함수 동기적 실행

CryptoJS 사용 예시(양방향 암호화)

const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);     //초기화 벡터

const cipherEncrypt = (word) => {
   const cipher = crypto.createCipheriv(algorithm, key, iv);   //암호화 객체 생성
   let encryptedData = cipher.update(word, 'utf-8', 'base64');   //암호화할 데이터 처리
   console.log('cipher.update : ' , encryptedData);
   encryptedData += cipher.final('base64');  //최종결과 생성
   console.log('cipher.final : ' , encryptedData);

   return encryptedData;
};

const decipher = (encryptedData) => {
   const decipher = crypto.createDecipheriv(algorithm, key, iv);  //복호화 객체 생성
   let decryptedData = decipher.update(encryptedData, 'base64', 'utf-8');
   decryptedData += decipher.final('utf-8');

   return decryptedData;
}

createCipheriv(algorithm, key, iv), createDecipheriv(algorithm, key, iv) - cryptoJS에서 대칭키 암호화, 복호화 위한 객체 생성

Node에서의 암호화 모듈 (2) - Bcrypt

Bcrypt 사용 예시

import bcrypt from 'bcrypt';

const salt = 10; 	//암호화 사용할 솔트값 정의

//암호화
const bcryptPassword = (password) => {
	return bcrypt.hashSync(password, salt);
};

//암호화값과 비교
const comparePassword = (password, dbPassword) => {
	return bcrypt.compareSync(password, dbPassword);
};

0개의 댓글