해싱(Hashing)

설하나·2022년 11월 14일
0

TIL

목록 보기
5/11

오늘의 Today I Learned (TIL)으로는 Hashing을 공부해보려고 한다. 자 가보자구~

✏️ 개념

﹖ 해싱(Hashing)

키(Key) 값을 해시 함수(Hash Function)라는 수식에 대입시켜 계산한 후 나온 결과를 주소로 사용하여 바로 값(Value)에 접근하게 할 수 하는 방법이다.
단방향 암호화방식이다.

﹖ 해시 함수(Hash Function)

키(Key) 값을 값(Value)이 저장되는 주소 값으로 바꾸기 위한 수식

해시함수의 조건

  • 입력의 크기에 제한이 없는 가변적인 길이를 수용해야 한다.
  • 출력은 고정된 길이를 가져야 한다.
  • 해시 함수(Hash Function)의 입력은 어떠한 값이 들어와도 계산이 쉬워야 한다.
  • 해시 함수(Hash Function)는 일방향성(One-way Function, 역변환 불가)이어야 한다.
  • 해시 함수(Hash Function)는 충돌(Collision)이 없거나 적어야 한다.

✏️ 암호화 구성요소

  • 평문(Plaintext) : 해독 가능한 형태의 메시지(암호화전 메시지)
  • 암호문(Cipertext) : 해독 불가능한 형태의 메시지(암호화된 메시지)
  • 암호화(Encryption) : 평문을 암호문으로 변환하는 과정
  • 복호화(Decryption) : 암호문을 평문으로 변환하는 과정

✏️ 암호화 종류

  • 양방향 암호화 ➡️ 암호화와 복호화 가능
  • 단방향 암호화 ➡️ 암호화는 가능하지만 복호화는 불가능

✏️ 사용 배경

웹 페이지 서버를 구성하면서 회원가입을 하면 데이터베이스에 비밀번호가 그대로 저장되는 것은 서비스를 제공하는데 있어서 다른 서비스까지 추가 해킹을 당하는 일이 발생할 수 있다.
따라서 비밀번호를 암호화하여서 데이터베이스에 저장해야하는데 암호화는 암호화에 사용된 키(비밀번호)를 통해 데이터를 복호화 할 수 있기 때문에 해싱이 등장하게 되었다.

하지만, 슈퍼컴퓨터가 등장하게 되면서 hash 함수만 알면 비밀번호가 될수 있는 모든 가지수의 정보들을 적은 테이블이 존재한다. 이러한 테이블을 레인보우테이블이라고 한다. 해당 테이블을 이용하여 무작위 공격을해서 해싱된 암호화를 알아 낼 수 있기 때문에 해쉬를 할때 salt를 사용한다.

✏️ salt

hash를 할때, 사용하는 무작위 숫자(소수점 가능)으로 원본 값을 알아내도 salt를 추가해주면서 가지수가 엄청나게 늘어나게된다. 따라서, 레인보우 테이블을 만들기도, 만들었어도 비밀번호를 찾아 내는 것 거의 불가능하다.
현재까지 많은 곳에서 사용중이므로 알아내는 것이 쉽지 않다.

✏️ 라이브러리

﹖ Bcrypt

레인보우 테이블 공격 방지를 위해 솔트(Salt)를 통합한 적응형 함수 중 하나로 SHA(Secure Hash Algorithm, 안전한 해시 알고리즘) 종류의 암호화는 GPU 연산에 유리한 32비트 논리 및 연산만 사용하기 때문에 GPU 연산을 이용한 공격에 취약하다고 한다.
그래서 Bcrypt 설계자는 Blowfish(브루스 슈나이어가 설계한 키(key) 방식의 대칭형 블록 암호)를 이용해 구현하였다고 한다.

@Mutation(() => User)
  async createUser(
    @Args('email') email: string,
    @Args('password') password: string,
    @Args('name') name: string,
    @Args({ name: 'age', type: () => Int }) age: number,
  ) {
		//비밀번호 암호화 하기
    const hashedPassword = await bcrypt.hash(password, 10.2); //암호화할 값 + salt값
    return this.usersService.create({ email, hashedPassword, name, age });
  }

bcrypt.hash(password,salt,callback)의 순으로 입력한다.

﹖ Crypto

Node.js 내장모듈인 Crypto를 이용해 특정 파일의 해시값을 생성한다.

const filename = process.argv[2]; // 읽을 파일 이름을 매개 변수로 써준다
const crypto = require('crypto');
const fs = require('fs');

const hash = crypto.createHash('sha256'); // sha-256 알고리즘 사용

const input = fs.createReadStream(filename);
input.on('readable', () => {
  const data = input.read();
  if (data)
    hash.update(data);
  else {
    console.log(`${hash.digest('hex')} ${filename}`);
  }
});

SHA-256을 비롯해 MD5, SHA-2 등을 지원.

📝 참고한 블로그

profile
Backend

0개의 댓글