[Express] 단방향 암호화와 양방향 암호화(대칭키, 비대칭키)

JuseungL·2024년 1월 10일
0

Node.js

목록 보기
5/8
post-thumbnail

공부하게된 계기

처음 회원가입 및 로그인을 구현할때 단순히 회원가입 시에 입력한 비밀번호를 단순히 그대로 DB에 저장하고 로그인 시에 입력받은 비밀번호와 비교하여 일치하면 유효하다, 불일치하면 유효하지 않다고 판단하는 로직으로 구현을 했었다.
그러나 만약 DB가 뚫리게 되면 해커가 사용자 정보 테이블에 접근하여 저장된 패스워드를 쉽게 볼 수 있다는 글을 이대로 두면 너무 무책임한 개발자가 될 것같으며 선택이 아닌 필수라는 생각이 들어 암호화에 대해 공부하고 실제로 적용해봤다.
이때 암호화에 대해 아는 것이 없어서 단방향 암호화와 양방향 암호화(대칭키, 비대칭키)에 대해서 먼저 공부해봤다.

암호화에 대해

들어가기에 앞서 암호화에 대해 간단히 이해해보자. 암호화에는 다양한 방법이 있다. 그 중 대표적으로 단방향양방향 암호화 방식이 있는데, 단방향은 암호화할 수는 있어도 복호화 해서 원래의 비밀번호를 알 수 없고, 양방향은 복호화 해서 원래의 비밀번호를 알 수 있다.
양방향 암호화에는 대칭형 암호화비대칭 암호화가 존재한다. 하나씩 알아보자.

1️⃣ 단방향 암호화

단방향 암호화는 평문을 암호화 할 수는 있지만 암호화된 문자를 다시 평문으로 복호화가 불가능한 방식이다. 주로 해시 함수(알고리즘)을 이용하여 단방향 암호화를 구현한다.

해시 함수(알고리즘)
이 해쉬 함수가 간단히 이야기하여 같은 입력 값에 같은 출력값이 나오는 게 보장되지만, 출력 값으로 입력 값을 유추할 수 없는 것을 의미한다.
다양한 종류의 해시 알고리즘이 있으며, 알고리즘마다 서로 다른 hash 길이를 가지기도 합니다.
그리고 해시 알고리즘은 공개되어 있기 때문에 해커에게도 공개됩니다. 따라서 이미 보안이 뚫린 해시 함수로 MD5, SHA-1, HAS-180 등이 있어 이것은 사용을 지양해야하고 보다 안전한 SHA-256, SHA-512 등을 사용하는 것을 지향해야 한다.

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

단방향 암호화의 한계
해시 알고리즘은 동일한 평문에 대하여 항상 동일 해시값을 갖기 때문에 특정 해시 알고리즘에 대해 특정 평문이 어떤 해시값을 갖는 지 알 수 있다. 이런 특징을 이용하여 해시 함수의 해시 값들을 대량으로 정리한 테이블이 존재하는데, 이를 레인보우 테이블(Rainbow Table)이라 부른다. 그리고 레인보우 테이블을 이용해 사용자의 정보를 해킹하는 공격을 레인보우 공격이라고 하는데 이러한 위험이 존재한다.
또한 해시 함수는 본래 데이터를 빠르게 검색하기 위해서 탄생됐다. 하지만 이러한 해시 함수의 빠른 처리 속도는 공격자에게 오히려 장점으로 작용된다. 공격자는 매우 빠른 속도로 임의의 문자열의 해시값과 해킹할 대상의 해시값을 비교해 대상자를 공격할 수 있다. (MD5를 사용한 경우 일반적인 장비를 이용하여 1초당 56억 개의 해시값을 비교할 수 있다)

🔆 단방향 암호화를 통해 로그인을 구현한다면?
유저가 회원가입 시에 비밀번호를 입력 했을 때 단방향 암호화를 한 출력값 자체를 데이터베이스에 저장해놓아서 DB가 털린다 하더라도 실제 입력 값을 알 수 없기 때문에 보안상 안전하게 느껴진다. 그렇기 때문에 대부분의 서비스에서 비밀번호 찾기를 하면 실제 내 비밀번호의 입력 값을 알려주는 것이 아니라 바로 재설정을 하는 것 같다.
그리고 유저가 로그인을 시도할때 비밀번호 입력값을 똑같은 해싱 함수로 단방향 암호화를 한 뒤 데이터베이스에 저장된 출력값과 비교하여 검증을 진행한다.
실제로는 솔팅(Salting), 키 스트레칭(Key Stretching) 등 추가적인 처리를 한다.
다음 게시물에서 다룰 것이다.

2️⃣ 양방향 암호화 - 대칭키

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

이 양방향 암호화 방식은 다시 대칭키와 비대칭키로 분리할 수 있다.
대칭키 방식은 암호화를 진행시 사용하는 키와, 암호문으로부터 평문을 복호화 할 때 사용하는 키가 동일한 시스템이다. 따라서 암호화를 진행할 때 사용한 키를 모른다면 해당 암호문은 다시 복호화 할 수 없다. 또한 키가 노출되면 누구나 암호문을 복호화할 수 있기 때문에 노출을 막기 위해 공개를 하면 안되기 때문에 비공개키 라고도 한다.

❗️여기서 사용되는 Key를 Secret 이라고 하는데 Private Key와는 다른 것이다. Secret은 노출을 비밀스럽게 해야하는 Key를 의미하고 Private Key는 절대 노출되어선 안되는 Key를 의미한다.

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

대칭키 암호화의 한계
대칭키 방식은 암호화와 복호화에 동일한 하나의 키를 이용하기 때문에 양쪽 모두 키를 가지고 있어야한다. 이때, 키를 주고 받는 과정에서 키가 유출될 우려가 있다. 특히 여러 상대방과 통신할 경우 각각의 키를 관리하는 것은 더욱 어려워 진다.
즉, 대칭키가 유출되면 키를 획득한 공격자는 암호의 내용을 복호화 될 문제가 있기 때문에 암호를 주고 받는 사람들 사이에 대칭키를 전달하는 것이 어려워 이런 배경에서 공개키 방식이 나오게 됐다.

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

비대칭키 암호화는 양방향 암호화 중 하나이기 때문에 암호화와 복호화 모두 가능하며 암호화를 진행할 때 키를 이용한다. 대칭키 암호화의 경우 암호화 할 때의 키와 복호화 할 때의 키가 동일했지만 비대칭키 암호화에서는 암호화 때 사용하는 키와 복호화 할 때 사용하는 키를 다르다.
일반적으로 다른 사람들에게 공개하는 Public Key와 절대 노출을 하지 않는 Private Key가 있다. 이 두 개의 키를 Key Pair라 한다. 대칭키 암호화는 암호화 할 때의 키와 복호화 할 때의 키가 동일 해서 키가 탈취 됐을 때 문제가 됐지만 비대칭키가 그것을 극복할 수 있다.
보통의 경우 데이터를 중요하게 다뤄야 하는 서버 측에서 Private Key를 사용하고,
누구나 사용해야 하는 클라이언트 측에서 Public Key를 사용하게 된다.

대표적으로 RSA 알고리즘을 사용한다.

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

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

이 과정에서 해커가 Public Key와 클라이언트에서 서버로 보내는 데이터를 탈취한다고 해도 해당 데이터를 확인할 수 없다. 사용자가 Public Key로 암호화 한 데이터는 서버가 가지고 있는 Private Key로만 복호화가 가능하기 때문이다. 따라서 Public Key가 공개되더라도, Private Key는 절대 공개 되어선 안된다.

Reference

https://velog.io/@yenicall/%EC%95%94%ED%98%B8%ED%99%94%EC%9D%98-%EC%A2%85%EB%A5%98%EC%99%80-Bcrypt
https://inpa.tistory.com/entry/NODE-%F0%9F%93%9A-crypto-%EB%AA%A8%EB%93%88-%EC%95%94%ED%98%B8%ED%99%94
https://velog.io/@jiheon/Node.js-crypto%EB%A1%9C-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-%EC%95%94%ED%98%B8%ED%99%94%ED%95%98%EA%B8%B0#salt-%EC%83%9D%EC%84%B1

profile
기록

0개의 댓글