암호화의 종류와 Bcrypt

류예린·2022년 8월 9일
13

1. 단방향 암호화


단방향 암호화란?

단방향 암호화는 평문을 암호화 할 수는 있지만 암호화된 문자를 다시 평문으로 복호화가 불가능한 방식이다. 주로 해시 알고리즘을 이용하여 단방향 암호화를 구현한다. 단방향 암호화를 사용하는 주된 이유는 메시지 또는 파일의 무결성(integrity)을 보장하기 위해서다. 원본의 값이 1bit라도 달라지게 된다면, 해시 알고리즘을 통과한 후의 해시값은 매우 높은 확률로 달라진다. 이를 통해 메시지나 파일의 원본 여부를 파악할 수 있다.

해시의 무결성을 보장하는 특징을 이용하여 저자 서명, 파일 또는 데이터의 식별자, 사용자의 비밀번호, 블록체인 등에서 활용되고 있다. 대표적인 해시 알고리즘으로는 MD5, SHA 등이 있다.

[그림1] 단방향 암호화


단방향 암호화의 한계

해시 알고리즘은 동일한 평문에 대하여 항상 동일 해시값을 갖는다. 따라서 특정 해시 알고리즘에 대해 특정 평문이 어떤 해시값을 갖는 지 알 수 있다. 이런 특징을 이용하여 해시 함수의 해시 값들을 대량으로 정리한 테이블이 존재하는데, 이를 레인보우 테이블이라 부른다. 그리고 레인보우 테이블을 이용해 사용자의 정보를 해킹하는 공격을 레인보우 공격이라고 한다.

또한 해시 함수는 본래 데이터를 빠르게 검색하기 위해서 탄생됐다. 하지만 이러한 해시 함수의 빠른 처리 속도는 공격자에게 오히려 장점으로 작용된다. 공격자는 매우 빠른 속도로 임의의 문자열의 해시값과 해킹할 대상의 해시값을 비교해 대상자를 공격할 수 있다. (MD5를 사용한 경우 일반적인 장비를 이용하여 1초당 56억 개의 해시값을 비교할 수 있다)


솔팅(Salting) & 키 스트레칭(Key Stretching)

✔️ 솔팅(Salting)

솔팅은 단방향 해시로 암호화를 진행할 시, 본래 데이터에 추가 랜덤 데이터를 더하여 암호화를 진행하는 방식이다. 추가 데이터가 포함 되었기 때문에 원래 데이터의 해시값에서 달라진다.

✔️ 키 스트레칭(Key Stretching)

단방향 해시값을 계산 한 후 그 해시값을 해시하고 또 이를 반복하는 방식이다. 최근에는 일반적인 장비로 1초에 50억 개 이상의 해시값을 비교할 수 있지만, 키 스트레칭을 적용하여 동일한 장비에서 1초에 5번 가량 비교할 수 있다. GPU(Graphics Processing Unit)를 사용하더라도 수백에서 수천 번 정도만 비교할 수 있다.

[그림2] Salting & Key Stretching






2. 양방향 암호화 - 대칭키


대칭키 암호화란?

양방향 암호화는 암호화된 값을 암호화 하기 이전 값으로 복호화 할 수 있다. 단방향 암호화와는 반대 개념으로 볼 수 있다. 양방향 암호화는 암호화 알고리즘과 키(Key)을 이용해서 암호화를 진행 하는데, 이 키를 통해 암호화된 값을 보호할 수 있다.

대칭키 방식은 암호화를 진행시 사용하는 키와, 암호문으로부터 평문을 복호화 할 때 사용하는 키가 동일한 시스템이다. 따라서 암호화를 진행할 때 사용한 키를 모른다면 해당 암호문은 다시 복호화 할 수 없다.

대표적인 대칭키 양방향 알고리즘으로는 AES가 있다. AES는 128, 192, 256 비트의 정해진 길이의 키를 사용한다. 암호화 진행시 키의 길이가 길어져 복잡할 수록 암호화도 복잡하게 된다. 그만큼 컴퓨터의 자원이 많이 필요하기 때문에 적절한 길이의 키를 사용해야 된다.

[그림3] 대칭키 암호화

대칭키 암호화의 한계

대칭키 방식은 하나의 키를 이용하므로 다른 사람과 대칭키 기반으로 암호화 통신을 할 경우 상대방도 사전에 같은 키를 갖고 있어야 한다. 하지만 키를 주고 받는 과정에서 키가 유출될 우려가 있다. 암호화 통신을 해킹 당할 수도 있다. 특히 여러 상대방과 통신할 경우 각각의 키를 관리하는 것은 더욱 어려워 진다.






3. 양방향 암호화 - 비대칭키


비대칭키 암호화란?

비대칭키 암호화 또한 암호화와 복호화 모두 가능하며, 암호화를 진행할 때 키를 이용한다. 다만 대칭키 암호화의 암호화는 키와 복호화하는 키 둘 모두 동일 했다면, 비대칭키 암호화에서는 암호화 때 사용하는 키와 복호화 할 때 사용하는 키를 다르게 사용한다. 일반적으로 다른 사람들에게 공개하는 Public Key와 절대 노출을 하지 않는 Private Key가 있다. 이 두 개의 키를 Key Pair라 부른다. 비대칭키 암호화는 대칭키 암호화의 고질적인 문제였던 키의 탈취 또는 관리의 단점 등을 보완할 수 있다. 암호화하는 키와 복호화 하는 키를 구분하기 때문이다.

[그림4] 비대칭키 암호화

데이터 암호화

사용자가 서버에 비대칭키 방식으로 데이터를 보내는 과정을 살펴보자.

  • 서버에 Key Pair를 발급하여 Public Key 사용자에게 전달한다.
  • 사용자는 데이터를 암호화 할 때 서버에서 받은 Public Key를 사용한다.
  • 서버는 사용자가 보낸 암호화된 데이터를 Private Key로 복화화해 내용을 확인한다.

이 과정에서 해커가 이미 Public Key를 훔쳤었고, 사용자가 서버로 데이터를 보낼 때 데이터 또한 중간에 가져간다고 해도 해커는 해당 데이터를 확인할 수 없다. 사용자가 Public Key로 암호화 한 데이터는 서버가 가지고 있는 Private Key로만 복호화가 가능하기 때문이다. 따라서 Public Key가 공개되더라도, Private Key는 절대 공개 되어선 안된다.

전자 서명

전자서명은 종이문서의 서명(인감)과 비슷한 개념이다. 전자문서에 서명한 사람이 누구이지 확인하고, 서명된 전자문서의 위·변조사실을 알 수 있도록 전자문서에 부착하는 특수한 형태의 디지털 정보를 말한다.

전자서명은 비대칭키 암호화를 통해 구현 할 수 있다. 비대칭 암호화의 Key Pair가 종이문서의 인감도장과 인감증명의 역할을 한다. Private Key(인감도장)는 서명자만 보관해 사용하고, 공개된 Public Key(임감증명)를 통해 서명이 진짜인지 아닌지를 판단 할 수 있다. 비대칭키를 이용한 전자서명 과정을 자세히 살펴보면 아래와 같다.

  • A가 Key Pair 발급 후 Public Key 공개.
  • A가 메시지를 작성하고, 본인의 전자 서명을 기입.
  • 전자 서명은 A가 작성한 메시지의 내용을 Private Key로 암호화한 값이다.
  • A의 메시지를 받은 B가 해당 메시지가 정말 A가 보낸 메시지인 지 확인하려 한다.
  • B는 공개된 A의 Publick Key로 전달 받은 전자서명을 복호화 한다.
  • 복호화의 내용과 메시지의 내용일 일치하면 A가 작성한 메시지라는 것을 확신할 수 있다.





4. Bcrypt


Salting & Key Stretching

단방향 암호화에 사용되는 해시 알고리즘은 동일한 평문에 대해 항상 동일 해시값을 갖는다. 따라서 특정 해시 알고리즘에 대하여 특정 평문이 어떤 해시값을 갖는지 알 수 있다.

또한 해시 함수는 본래 신속히 데이터를 검색하기 위해 탄생됐다. 따라서 공격자는 매우 빠른 속도로 임의의 문자열의 해시값과 해킹할 대상의 해시값을 비교하여 대상자를 공격할 수 있다.

이런한 문제를 보안하기 위해 단방향 암호화를 진행할 때 솔팅(Salting)키 스트레칭(Key Stretching)을 적용 시킨다.

✔️ 솔팅(Salting)

솔팅은 단방향 해시 함수 암호화를 진행 할 때 본래 데이터에 추가적으로 랜덤한 데이터를 더하는 방식이다. 원래 데이터에 추가 데이터가 포함 되었기 때문에 이전의 해시값과 달라진다.

✔️ 키 스트레칭(Key Stretching)

단방향 해쉬값을 계산 한 후, 그 해쉬값을 또 다시 해시하고 또 이를 반복하는 방식이다. 최근 일반적인 장비로도 1초에 50억 개 이상의 해시값을 비교할 수 있다. 하지만 키 스트레칭을 적용하면 동일 장비에서 1초에 5번 정도만 비교할 수 있다. GPU(Graphics Processing Unit)를 사용하더라도 수백에서 수천 번 정도만 비교할 수 있다.

[그림5] Salting & Key Stretching

Bcrypt 란?

Bcypt는 브루스 슈나이어가 설계한 키(key) 방식의 대칭형 블록 암호에 기반을 둔 암호화 해시 함수다. Niels Provos 와 David Mazières가 설계했다. Bcrypt는 레인보우 테이블 공격을 방지하기 위해 솔팅과 키 스트레칭을 적용한 대표적인 예다.

✔️ 구조

$2b$12$76taFAFPE9ydE0ZsuWkIZexWVjLBbTTHWc509/OLI5nM9d5r3fkRG
 \/ \/ \____________________/\_____________________________/
Alg Cost       Salt                        Hash
  • 2b : 해시 알고리즘 식별자
  • 12 : Cost Factor로 Key Stretching의 수 (2의 12승번)
  • 76taFAFPE9ydE0ZsuWkIZe : 16Byte 크기의 Salt, Base64로 인코딩된 22개의 문자
  • xWVjLBbTTHWc509/OLI5nM9d5r3fkRG : 24Byte의 해시 값, Base64로 인코딩된 31개의 문자

✔️ 검증

Bcrypt는 단방향 해시 알고리즘이다. 따라서 복호화가 불가능하다. Bcrypt의 검증은 암호화된 값이 가지고 있는 알고리즘, Cost Factor, Salt를 이용한다.

  1. 비교하고 싶은 평문을
  2. 암호화된 값이 가지고 있는 알고리즘, Cost Factor, Salt을 이용해 해시를 진행한 후
  3. 암호화된 값과의 비교를 통해 검증을 진행한다.





5. Node.js에서 bcrypt 사용하기


Bcrypt 설치

$ npm install bcrypt --save

Bcrypt로 비밀번호 암호화 (Async)

const bcrypt = require("bcrypt"); // (1)

const password = 'password'; // (2)
const saltRounds = 12; // (3)

const makeHash = async (password, saltRounds) => {
  return await bcrypt.hash(password, saltRounds); // (4)
}

const main = async () => {
  const hashedPassword = await makeHash(password, saltRounds);
  console.log(hashedPassword);
}

main()
=> b'$2b$12$76taFAFPE9ydE0ZsuWkIZexWVjLBbTTHWc509/OLI5nM9d5r3fkRG'
  • (1): bcrypt 모듈 import
  • (2): 암호화 할 평문
  • (3): Cost Factor
  • (4): hash() method로 암호화, 첫번째 인자로 암호화 하고 싶은 평문이 두번째 인자로 Cost Factor가 들어간다.

Bcrypt 검증

const checkHash = async (password, hashedPassword) => {
  return await bcrypt.compare(password, hashedPassword) // (1)
}

const main = async () => {
  const hashedPassword = await makeHash("password", 12);
  const result = await checkHash("password", hashedPassword);
  console.log(result);
};

main()
=> true(or false) // (2)
  • (1): compare() method로 평문과 암호화된 값 비교, 첫번째 인자로 평문이 두번째 인자로 암호화된 값이 들어간다.
  • (2): 비교 결과, 평문과 암호화된 값을 비교해서 같으면 true를 다르면 false가 return된다.









6. 정리


  • 단방향 암호화는 해시 알고리즘을 사용한 암호화는 가능, 그러나 복호화는 불가능한 암호화 방법이다.
  • 단방향 암호화는 해시 알고리즘을 기반으로 만들어졌다.
  • 솔팅(Salting)과 키 스트레칭(Key Stretching) 기법을 이용하여 단방향 암호화의 단점을 보안할 수 있다.
  • Bcrypt는 레인보우 테이블 공격을 방지하기 위해 솔팅과 키 스트레칭을 적용한 대표적인 예다.
  • Bcrypt는 단방향 해시 알고리즘이기 때문에 복호화가 불가능하다. 따라서 비교하고 싶은 평문을 암호화된 값이 가지고 있는 알고리즘, Cost Factor, Salt을 이용해 해시를 진행한 후 암호화된 값과의 비교를 통해 검증을 진행한다.
  • 양방향 암호화에는 대칭키 방식과 비대칭키 방식이 존재. 암호화와 복호화를 진행 할 때 Key를 이용한다.
  • 대칭키 방식의 양방향 암호화는 암호화와 복호화에 동일한 Key를 사용하며, Key의 노출은 보안에 취약하다.
  • 비대칭키 방식의 양방향 암호화는 암호화와 복호화에 서로 다른 Key를 사용하며, 대칭키 방식의 문제였던 Key 노출 문제를 해결할 수 있다.
profile
helloworld

3개의 댓글

comment-user-thumbnail
2023년 7월 14일

좋은 게시글 감사합니다.

답글 달기
comment-user-thumbnail
2024년 3월 19일

잘 읽었습니다!

답글 달기