[NodeJS] 비밀번호 암호화 - 해시(Hash), 솔트(Salt)

seonjeong·2023년 6월 21일

NodeJS

목록 보기
13/19
post-thumbnail

비밀번호를 암호화할 때, 일단 암호화 되면 복호화가 어렵기 때문에 단방향 암호화 기법을 사용한다.
그래서 비밀번호 찾기를 하면 임시 비밀번호를 발급해주거나 다시 설정하게 하는 경우가 대다수이다.

💖 해시(Hash) 암호화 알고리즘

  • 단방향 암호화 기법
  • 해시 함수를 이용하여 고정된 길이의 암호화된 문자열로 바꾸는 것
  • 해시 알고리즘마다 hash길이가 다르고 이미 보안이 뚫린 것들도 있다
    • MD5, SHA-1, HAS-180 ❌
    • SHA-256, SHA-512 등 사용 권장 ✔️

🔥 해시 함수

  • 임의의 길이를 가진 데이터를 입력받아 고정된 길이의 값, 즉 해시값을 출력하는 함수
  • 입력되는 값 = 키(key), 그 출력값 = 해시(hash)
  • 복수의 입력값들이 동일한 출력값을 공유하는 경우가 가능 -> 해시 충돌

-> John Smith와 Sandra Dee 키들 사이에 충돌이 발생

🔥 해시 테이블

  • 해시 함수를 활용하여 키-값 쌍으로 데이터를 관리하는 자료구조
  • 해시 함수를 거치면서 각각의 키는 해시값(인덱스, 해시코드 등)을 생성하고, 생성된 해시는 특정한 버켓에 연결된다

🔥 해싱

  • 특정 입력값에 대해 해시함수를 거치면서 특정한 데이터를 생산하는 작업
  • 출력값은 다양한 타입을 지닐 수 있다

🔥 레인보우 테이블

  • 해시함수를 사용하여 만들어낼 수 있는 값들을 대량으로 저장한 표
  • 해시 값을 통해 본래의 값을 추측할 수 있다
  • 솔트(salt)를 활용하여 이것을 막을 수 있다


💖 솔트(Salt)

  • 해시 함수에 넣기 전에 키를 변형시키는 데 활용할 임의의 문자열 데이터. 소금치듯 추가하는 것
  • 솔트를 통해 1차적으로 변형시키면 원래의 값을 유추하기가 어려워진다
  • 개별적으로 고유의 솔트를 갖고 있어야 더욱 효과적이다

💖 비밀번호 암호화하기

🔥 bcrypt

  • Blowfish 암호를 기반으로 설계된 암호화 함수이며 현재까지 사용중인 가장 강력한 해시 메커니즘 중 하나
  • SHA는 일반적으로 GPU연산에 유리한 32비트 논리 및 산술 연산만 사용하기 때문에, 공격자가 빠른연산으로 공격할 수 있다. 이로인해 SHA가 아닌 Blowfish를 이용하여 구현되었다

1. 설치

npm install bcrypt

2. 코드 작성

// HashEncryptionUtil
import bcrypt from "bcrypt";
import { BadRequest } from "../errors/BadRequest";
import { InternalServerError } from "../errors/InternalServerError";

export class HashEncryptionUtil {
  private saltRounds: number;

  constructor(saltRounds: number) {
    this.saltRounds = saltRounds;
  }

  // 비밀번호 암호화
  public encryptPassword = async (password: string) => {
    try {
      const salt = await bcrypt.genSalt(this.saltRounds); // salt
      const hashedPwd = await bcrypt.hash(password, salt); // hash function
      return hashedPwd;
    } catch (error) {
      console.log(error);
      throw new InternalServerError("비밀번호 암호화 실패");
    }
  };

  // 비밀번호 확인
  public comparePassword = async (password: string, hashedPwd: string) => {
    try {
      const match = await bcrypt.compare(password, hashedPwd);
      if (match === true) return match;
    } catch (error) {
      console.log(error);
      throw new BadRequest("비밀번호 확인에 실패했습니다.");
    }
  };
}
// UserService 회원가입 비즈니스 로직에 추가
// 비밀번호 암호화
const hashEncryptionUtil = new HashEncryptionUtil(10);
const hashedPwd = hashEncryptionUtil.encryptPassword(pwd);

https://www.npmjs.com/package/bcrypt




Reference

https://krauser085.github.io/encryption/
[보안] 비밀번호 암호화: 해쉬와 솔트
https://inpa.tistory.com/entry/NODE-%F0%9F%93%9A-bcrypt-%EB%AA%A8%EB%93%88-%EC%9B%90%EB%A6%AC-%EC%82%AC%EC%9A%A9%EB%B2%95#bcrypt

profile
🦋개발 공부 기록🦋

0개의 댓글