[새싹 x 코딩온] 웹 풀스택 영등포 5기 8주차 회고

용가리🐉·2023년 12월 5일
0
post-thumbnail

📌 환경변수 이론

📣 환경변수

  • 환경변수는 운영체제(OS)나 애플리케이션에서 사용되는 데이터 값을 저장하는 메커니즘
  • 프로그램의 동작을 조정하거나 구성
  • Node.js에서도 이러한 환경변수를 활용하여 애플리케이션의 설정과 동작을 조정

📣 Node.js 환경변수

  • Node.js에서는 process.env 객체를 통해 환경변수에 접근
const ps = process.env;
console.log(ps);

🟠 .env

  • 환경변수를 관리하기 위해 .env 파일을 사용하는 것이 일반적
  • Git 저장소에 업로드 하지 말아야 함!
  • FileZila를 통해 서버에 파일만 업로드

📌 환경변수 실습

📣 환경변수 사용

npm install dotenv
// .env 생성
NAME = sesac
NODE = dev

////////////
require("dotenv").config(); // .env 파일의 환경변수를 읽어옴

app.get("/", (req, res) => {
	res.send("log");
  	console.log(process.env.NAME);
  	console.log(process.env.NODE);
});

📣 package.json 사용

  • Node.js 프로젝트에서 운영 체제 간 환경변수 설정을 도와주는 모듈
npm install cross-env
  • 다음과 같이 설정될 경우, nodemon이 아닌 npm start로 시작 가능
"scripts": {
  "start": "cross-env NODE_ENV=develeopment node index.js",
  "start:prod": "cross-env NODE_ENV=production node index.js",
  "test": "echo \"Error: no test specified\" && exit 1"
},

📌 암호화 이론

  • 해당 부분 없이 단순 DB 작업을 통해 로그인, 회원가입 기능을 구현한다면, DB에 비밀번호가 그대로 저장 → 해킹 위험

📣 종류

🟠 단방향 암호화

  • 데이터 무결성을 검증하는데 주로 사용, 패스워드 저장 등에서도 활용
  • 복호화 불가능 → 원본 데이터 복원 불가능
  • 동일한 데이터에 대해서는 항상 동일한 해시 값이 생성됨
    • 서로 다른 데이터에 대해서도 같은 해시 값이 나올 수 있음(충돌)
  • 미세한 데이터 변화에도 해시 값은 완전히 다름
  • 주로 Hash 함수(MD5, SHA-1, SHA-256 등)를 사용하여 구현
  • 충돌 경우가 있을 수 있지만 그 확률이 매우x5 낮음

📎 해시(Hash)

해시 함수에 의해 얻어지는 값

  • 해시 함수 (Hash Function) = 해시 알고리즘
    • 임의의 크기의 데이터를 고정된 크기의 데이터로 변환하는 함수
    • 키(key) : 매핑 전 원래 데이터 값
    • 해시 값(hash value) : 매핑 후 데이터 값
    • 해싱(hashing) : 매핑하는 과정

📎 해시 함수(해시 알고리즘)

  • SHA-256 (Secure Hash Algorithm 256-bit)
    • 256비트 해시 값, 충돌 저항성 및 보안성 높음
    • 많은 애플리케이션에서 데이터 무결성 검증이나 디지털 서명에 사용
  • SHA-512 (Secure Hash Algorithm 512-bit)
    • 512비트 해시 값, 충돌 저항성 및 보안성 높음
    • 더 큰 해시 값을 생성하기 때문에 좀 더 안전한 알고리즘

충돌 저항성이 약하기 때문에 사용하지 않는 알고리즘 : MD5, SHA-1

🟠 양방향 암호화

  • 데이터 기밀성을 유지하거나 안전한 통신을 위해 사용
  • 공개키와 대칭키 암호화를 조합하여 데이터 보안을 유지하면서 처리 속도를 향상
    • 공개키(비대칭키) : 암호화 복호화에 사용되는 키가 다름
      • 공개키로 암호화된 데이터는 개인키로만 복호화 가능
      • 개인키로 암호화된 데이터는 공개키로만 복호화 가능
  • HTTPS와 같은 프로토콜로 클라이언트-서버 통신을 보호하여 안전한 웹 통신을 제공

📎 대칭키 암호화 알고리즘

대칭키 사용 : 암호화와 복호화에 동일한 키를 사용하므로 키 관리가 중요

  • AES (Advanced Encryption Standard)
    • 다양한 키(비밀 값)과 블록(암호화할 데이터)을 제공
    • 종류 : AES-128, AES-192, AES-256
    • 빠른 처리 속도, 다양한 플랫폼에서 구현 용이
    • ECB, CBC, CFB, OFB, CTR 등 다양한 운용 모드를 통해 데이터 블록을 처리
  • DES (Data Encryption Standard)
    • 초기에 개발된 56비트 키와 64비트 블록 크기를 가지는 대칭키
    • Triple DES: 3DES는 DES를 여러 번 적용하여 암호화하므로 보안성은 높아지지만, 처리 속도가 느려짐

📎 AES 블록 암호화 운용 모드

  • ECB (Electronic Codebook)
    • 각 데이터 블록을 독립적으로 암호화
    • 같은 입력 블록에 대해 항상 같은 암호문 생성 → 패턴이 누출될 수 있음
    • 보안성이 낮아 주로 간단한 암호화 작업에 사용되고, 중복되는 패턴이 없는 데이터에 적용될 때 더 안전하게 사용
  • CBC (Cipher Block Chaining)
    • 이전 블록의 암호문과 현재 블록의 평문을 XOR 연산하여 암호화
    • 초기 블록은 초기화 백터(IV)로 암호화
    • 이전 블록의 암호문이 현재 블록에 영향을 주기 때문에 같은 평문에 대해 다른 암호문이 생성됨 → 패턴이 누출되지 않음

📎 공개키 암호화 알고리즘

두 개의 키 : 공개키와 개인키라는 두 개의 키 쌍을 사용

  • 공개키는 다른 사람과 공유되며, 개인키는 오직 소유자만 알고 있어야 함
  • RSA (Rivest-Shamir-Adleman)
    • 대칭키 암호화보다 복잡하지만 효율적으로 사용
    • 종류: RSA-1024, RSA-2048, RSA-3072, RSA-4096
  • ECC (Elliptic Curve Cryptography) : 타원 곡선을 기반
    • 작은 키 길이로도 강력한 보안성을 제공
    • 종류: ECC-192, ECC-256, ECC-384

📌 암호화 실습

📣 Crypto

암호화 알고리즘이 모여 있는 패키지

const crypto = require("crypto");

📣 Crypto 암호화

  • createHash(algorithm)
    • 해시를 만들기 위해 사용하는 함수 → 지정한 해시 알고리즘(parameter로 전달됨)을 사용하여 해시 객체 생성
const crypto = require("crypto");

const createHasedPassword = (pw) => {
	return crypto.createHash("sha512").update(pw).digest("base64");
};
  • update() : parameter로 전달된 데이터가 해시 함수에 입력으로 사용
  • digest() : 해시를 만들 때 인코딩 방식 설정
    • base64 : 64개의 가능한 문자로 데이터를 인코딩하는 방식
      • 64개의 문자 중 62개는 영문 대소문자와 10진수 숫자로 구성
      • 나머지 두 개의 문자는 인코딩과 디코딩 과정에서 추가적인 문자로 사용
    • hex : 16진수 인코딩

해시함수 한계! 레인보우 테이블

  • 레인보우 테이블(Rainbow Table) : 해시함수를 사용해 만들어낼 수 있는 값들을 대량으로 저장해놓은 표
  • 해시 함수를 사용하여 암호화된 비밀번호를 빠르게 역추적하여 원본 비밀번호를 찾는 공격 기법

🟠 암호화 보완법

  • salt : 입력한 값에 salt라는 특정 값을 붙여 변형시키는 것
  • 해시 함수 반복 : 해시 함수를 여러번 돌려 본래의 값을 예측하기 어렵게 만드는 것

  • pbkdf2Sync(password, salt, iterations, keylen, digest)
    • 비밀번호 기반 키 도출 함수(PBKDF, Password-Based Key Derivation Function)를 동기적으로 실행
    • 버퍼 반환
    • 주로 사용자 비밀번호를 저장할 때 사용
const salt = crypto.randomBytes(16).toString('base64'); // 솔트 생성
const iterations = 100000; // 반복 횟수
const keylen = 64; // 생성할 키의 길이
const digest = 'sha512'; // 해시 알고리즘

const createPbkdf = (pw) => {
	return crypto.pbkd2Sync(pw, salt, iterations, keylen, digest).toString('base64');
};

🟠 Crypto 검증

const verifyPassword = (password, salt, dbPassword) => {
	const compare = crypto.pbkdf2Sync(password, salt, iterations, keylen, digest).toString('base64');
  
  	if (compare === dbPassword) return true;
  	
  	return false;
};
  • Crypto는 단뱡향 알고리즘이기 때문에 복호화 불가능 → 입력한 값과 동일한 알고리즘을 이용해 다시 암호화를 하여 비교

  • createCipheriv(algorithm, key, iv) / createDecipheriv(algorithm, key, iv) : 대칭키 암호화와 복호화를 위한 객체를 생성
const algorithm = "aes-256-chc"; // 알고리즘
const key = crypto.randomBytes(32); // 256비트 키
const iv = crypto.randomBytes(16); // 초기화 벡터

const cipherEncrypt = (word) => {
	const cipher = crypto.createCipheriv(algorithm, key, iv); // 암호화 객체 생성
  	let encryptedData = cipher.update(word, "utf-8", "base64"); // 암호화할 데이터 처리
  	// word: 암호화 원본 데이터
  	// "utf-8": 입력 인코딩
  	// "base64": 출력 인코딩 
  	encryptedData += cipher.final("base64");
  	
  	return encryptedData;
};

🟠 Crypto 복호화

const decipher = (encryptedData) => {
	const decipher = crypto.createDecipheriv(algorithm, key, iv);
  	let decryptedData = decipher.update(encryptedData, "base64", "utf-8"); // 암호화할 데이터 처리
  	// encryptedData: 암호화 데이터
    // "base64": 입력 인코딩 
  	// "utf-8": 출력 인코딩
  
  	decryptedData += decipher.final("utf-8");
  	console.log("Decrypted:", decryptedData);
  
  	return encryptedData;
};

📣 Bcrypt

비밀번호를 암호화하는 알고리즘 중 하나

  • Blowfish 암호를 기반으로 설계된 암호화 함수
  • 현재까지도 사용 중인 가장 강력한 매커니즘 → 강력한 보안이 필요할 때 적합
    • 해싱이 느리고 비용이 많이 듦
    • 원본 데이터를 복원하는 기능이 없음

📣 Bcrypt 암호화

npm install bcrypt
const bcrypt = require("bcrypt");

const salt = 10; // 암호화에 사용할 salt의 수준 설정. 정수 사용

// 비밀번호 해싱 함수
const bcryptPassword = (password) => {
	return bcrypt.hashSync(password, salt);
};

// 원본 비밀번호와 해시된 비밀번호가 일치하는 확인하는 함수
const comparePassword = (password, dbPassword) => {
	return bcrypt.compareSync(password, dbPassword);
};
profile
자아를 찾아 떠나는 중,,,

0개의 댓글

관련 채용 정보