올바른 비밀번호 암호화 알고리즘 선택하기 (안전하게 패스워드 저장하기)

HYEONG HWAN, MUN/ 11월 8, 2022/ 미분류/ 2 comments

https://blog.lael.be/post/11518

 

 

암호화에 대한 마음에 드는 설명글이 없어서 내가 하나 작성해 보려고 한다.


암호화(暗號化)란?

먼저 “암호화“의 단어의 뜻에 대해 알아보도록 하자.
많은 사람들이 암호화를 제대로 구현하지 못하는 이유는, 단어의 뜻을 올바르게 이해하지 않고 구현하기 때문이다.

암(暗) : 어두울 암
호(號) : 부를 호

어둡게 부르는 것을 암호라고 한다.

 

몇가지 암호화의 예제를 알아보자.


원본 메세지(original message) : HELLO
암호화 메세지 : H1E1L1L1O1
암호화 방식 : 각 문자 뒤에 1 문자를 삽입.

단점 : 암호화 방식(1을 제거)을 알면 손쉽게 원본을 알 수 있음


원본 메세지(original message) : HELLO
암호화 메세지 : HLL
암호화 방식 : 원본 메세지에서 모음(AEIOU) 알파벳을 제거.

단점 : 원본 메세지가 손실됨. HOLLA 같은 메세지와 동일한 암호화 결과를 만들어내는 충돌(collision)문제가 있음.


원본 메세지(original message) : HELLO
암호화 메세지 : PEQQO
암호화 방식 : H -> P, L -> Q 로 교체.

단점 : 암호화 규칙(대응 교체)를 통해 원본 메세지를 쉽게 확인 가능


원본 메세지(original message) : HELLO
암호화 메세지 : OLLEH
암호화 방식 : 문자열을 역순으로 정렬

단점 : 다시 역순으로 정렬하면 원본 메세지를 쉽게 확인 가능.


위의 모든 방식이 다 암호화이다. 위의 파란 문자를 보고 원본을 알아낼 수 있겠는가?
한국에서는 “알아보기 힘들면” 다 암호화라고 간주한다.
이것이 많은 사람들이 암호화를 제대로 구현하지 못하는 이유이다.

한글의 암호화에 대응되는 영어 단어는 다음의 3가지이다.

 

한국어 단어 암호화에 대응하는 영어 단어

  • Obfuscation
  • Encryption
  • Hashing

 

암호화 메세지를 원본 메세지로 변환하는 것을 복호화 라고 한다.
암호화라는 단어와 다르게, 복호화와 대응되는 영어 단어하나 뿐이다.

 

한국어 단어 복호화에 대응하는 영어 단어

  • Decryption

글의 제목을 다시 생각해 보자.
올바른 암호화 방식” 이란 어떤 것일가?
이것은 암호화 하는 대상암호화 목표에 따라 달라진다.

 

Obfuscation (난독화)

한국에서 쓰이는 “암호화“의 단어 뜻은 “난독화“를 의미한다. 한국에서는 사람이 인지하기 어려우면 다 암호화 라고 부른다.
난독화는 읽기가 어려울 뿐, 적절한 해석기를 사용하면 원본 메세지의 의미를 알 수 있다. 적절한 해석기란 미리 공개되고 정의된 규칙 수행을 하는 프로그램을 뜻한다.

예시 : 아버지가방에들어가신다

예시 : 아스키 변환

예시 : Base64

base64는 진법 변환일 뿐이다. 사람이 이해하기 어렵지만 그 뿐이다.

 

 

난독화 사용처

난독화는 데이터 표현을 위해서 어쩔 수 없이 내용이 공개되어야 하지만, 사람이 쉽게 이해하는 것을 원하지 않을때 사용한다.

  • js minify
  • css minify
  • 통신을 위한 base64 encode 변환
  • 숫자 값을 이해하기 어렵하기 위해 base62 encode 변환

 

난독화 예제

echo base64_encode("lael test");
// RESULT : bGFlbCB0ZXN0

 

echo implode('', unpack("C*", "lael test"));
// RESULT : 1089710110832116101115116

비전문가가 봤을땐 암호화 같이 보이지만, 위 방법은 “암호화가 아니라 난독화“이다. 민감한 정보(특히 비밀번호)의 저장과 전송에 사용하지 말 것.

 

 

Hashing

해싱은 무결성을 검증하기 위해서 개발되었다.

해싱 함수는 어떠한 길이의 값이 입력되어도, 고정된 길이의 결과를 반환하는 함수이다.

 

대표적인 해싱함수의 예주민등록번호 마지막 자리 이다.
주민등록번호 마지막 자리 숫자는 앞의 12자리 숫자의 해싱 결과이다.

해싱 함수의 예제 : Modulo Operation (나머지 연산. 보통 2, 10, 16 을 쓴다)

  • 123456 => 6
  • 1757 => 7
  • 974115 => 5
  • 3 => 3

해싱 함수의 예제 : Square Operation (제곱법)

  • 123456 => xxx36 => 6
  • 1757 => xxx49 => 9
  • 974115 => xxx25 => 5
  • 3 => xxx9 => 9

 

같은 OUTPUT 이 나오는 것을 충돌(collision) 이라고 한다. 따라서 충분히 긴 결과가 나오는 해싱 함수를 사용하는 것이 좋다. (업계 표준은 SHA256 이다. 간혹 SHA512 해시를 제공하는 곳들도 있다.)

예시 : http://releases.ubuntu.com/jammy/ (우분투 운영체제 다운로드 페이지)

64개의 영어단어를 통해서, 3.6GB 의 파일이 온전하게(무결성) 다운 받아졌는지 확인할 수 있다.

참고로 SHA256 은 결과물이 256bit 이다. 이것은 32Byte 이다. 그리고 숫자표기에는 0123456789abcdef 의 16진법을 사용하는 hex 를 주로 사용한다.
1Byte 는 8Bit 이고 표현범위는 0~255 이다. 따라서 2개의 hex 값을 사용해서 1개의 Byte를 표시한다.
32Byte 는 hex로 표현하면 2배인 64글자가 된다.

 

- Hexa-decimal 을 사용하는 이유
Byte 의 범위는 0 ~ 255 이다. 이에 대응하는 코드표는 아스키 코드표가 있는데, 줄바꿈, 백스페이스, 페이지업, 컨트롤 등등 화면에 표시할 수 없는 특수키와 매핑이 되어 있다.
따라서 통신 및 어플리케이션에서 사용할 수 있게, 사람이 인식할 수 있는(human readable, printable) 문자로의 변환이 필요로 했고, hexa-decimal(2자리의 16진수)이 채택되었다.

물론 exe 등 바이너리 빌드하거나, DB에서 bin 형태로 저장하는등, byte 자체로 사용하는 경우도 있다.

 

Hash function list
no 해시명 Family 출시일 개발자 해시 결과물 BIT 기타
1 md5 1991년 Ronald Lorin Rivest 128 취약함
2 sha1 SHA-1 1995년 미국 국가안보국(NSA) 160 취약함
3 sha224 SHA-2 2001년 미국 국가안보국(NSA) 224
4 sha256 SHA-2 2001년 미국 국가안보국(NSA) 256 **널리 사용됨**
5 sha384 SHA-2 2001년 미국 국가안보국(NSA) 384
6 sha512 SHA-2 2001년 미국 국가안보국(NSA) 512
7 SHA3-224/SHA3-256/SHA3-384/SHA3-512 SHA-3 2015년 Guido Bertoni/Joan Daemen/Michaël Peeters/Gilles Van Assche -

 

SHA256 은 2023년 현재, 비트코인, 한국의 인터넷뱅킹, MS Windows 업데이트서버 에서 사용하고 있다.
2023년 현재 ISMS-P 기준으로는 SHA256 이상의 해시함수 사용을 권장하고 있다.

라엘이의 개인 견해 : 안전하고, 호환성 뛰어난(= 여기저기서 다 쓰고 있는) SHA256 으로 당신의 시스템을 설계하기를 권장합니다. 간혹, 경험이 부족한 개발 리더가 최신만을 쫒아서 SHA3를 선택하는 경우가 있는데, SHA에 대해서 손으로 한번이라도 풀어본 경험이 없는 이상은 그런 도전을 하지 않았으면 좋겠습니다.

 

TIP : 해시 함수가 취약하다 라는 것의 의미
해시 함수는 무결성의 용도로 개발되었습니다. 그런데 다른 두개의 파일이 동일한 해시를 생성해 버린다면, 그것은 해시함수의 정의에 위배되는 것이고, 취약한 것으로 간주됩니다.

TIP : SHA-3 해시함수는 SHA-2 함수가 취약해서 개발된 것이 아닙니다. 아주 먼 훗날 SHA-2 가 혹시나 취약한 것으로 간주될때 대체할 알고리즘을 개발한 것입니다.
미국 국립표준기술연구소(NIST)는 현재 SHA-2를 철회하거나 개정된 보안 해시 표준에서 제거할 계획이 없다고 밝혔습니다.
즉, SHA-3 는 예비용이지, SHA-2 가 취약해서 개발된 것이 아님!

TIP : SHA3 써보는 것은 추천한다. 하지만 개발할 소프트웨어 프로젝트에서 SHA3를 선택하지는 말아라.

TIP : sha256 은 2023년 현재 양자컴퓨터에서 안전하다. (sha 256 quantum safe)

 

비밀번호동등비교만 하면 되기 때문에 해시함수를 사용해서 저장해야 합니다.

예전에 어떤 분이 인터넷에서 이상한 글 읽고 와서, 해시함수는 암호화 함수가 아니기 때문에 비밀번호 저장에 쓰면 안된다고 우기던 분 있었는데, 정말 난감했습니다.
비밀번호는 Encryption 을 하면 안되고 Hashing을 해야 합니다. (비가역적이어야 함)

 

 

암호 저장의 관점에서, 해시 함수의 문제

SHA256의 문제점이 아닙니다. 비밀번호 암호화 관점에서의 해시 함수의 문제입니다.

- 가시성 : 해시 함수는 동일한 입력에 대해서 동일한 결과를 생성합니다.

따라서 해시 함수의 결과를 보고, 동일한 비밀번호를 사용하는 사용자를 식별할 수 있습니다. (이 문제는 salted hash 라는 기법으로 해결할 수 있음)

 

- 고성능 : 해시 함수는 함수입니다. 즉 매우 고성능으로 연산할 수 있습니다. 공격자는 고성능의 하드웨어를 사용해서 무차별 대입공격을 할 수 있습니다. (이 문제는 Key derivation function 라는 기법으로 해결할 수 있음)

 

Encryption

이것은 메세지를 온전하게 전달하는 통신방법이다. 즉, 원본을 확인해야 할 때 사용한다. 당연한 이야기 이지만 비밀번호 저장에 Encryption 을 사용하면 안된다.

우리가 무심코 사용하는 HTTPS 은 Encryption 통신 기법이다. 종단간(End-to-End) 암호화 라는 표현을 쓰는데, 중간에서 탈취해도 내용을 알아볼수 없도록 하는 것이 목표이다.
하지만 종단간에는 내용을 알아야 하기 때문에 반드시 Decryption 단계가 필요하다.

 


실전 예제

내가 작성한 코드를 공개된 프로그램에서 실행되어야 하지만 다른사람이 확인하는것은 막고 싶을때

- 난독화

 

비밀번호를 저장할 때 -> 해싱

핵심은 원본 메세지를 알 수가 없어야 한다는 것이다.

 

개인정보를 저장할 때 -> 암호화화식별이 불가능해야하고 원본을 확인해야할 때 사용한다.

단점은 검색이 안된다는 점이다. 지나친 일치를 막으라는 권고도 있다.

 

 


더 알아보기

해킹과 보안은 한끝 차이이다. IT업을 하다보면 다양한 취약한 코드를 경험하게 된다. 그것을 취약하지 않게 수정하면 보안이 되고, 악용(오용)하면 해킹이 된다.

해커의 마인드와 보안 관리자의 마인드를 모두 가지고 있는 것이 좋다.

자신이 해커라는 생각을 가지고 작업에 임할것.

 

비밀번호

원본 비밀번호 문자는 알아야할 필요가 없다. 그래서 반드시 해시 함수를 통해서 암호화 해야한다.

비밀번호 해시함수는 적절히 느려야 한다. sha512 보다 sha256 을 사용할 것!

 

 

키 스트래칭 , 이니셜벡터, salt

 

레인보우테이블

 

브루트포스

 

알고리즘 종류

선택

 

코드 예제

pbkdf2-sha256

 

봉투 암호화

 

2 Comments

  1. 역시 글을 잘 쓰십니다.
    저도 많이 본받고 배우겠습니다.

    1. 부족한 글 읽어주셔서 감사합니다.
      goorm it 사이트 둘러봤는데 멋진것 같습니다!

Leave a Comment

작성하신 댓글은 관리자의 수동 승인 후 게시됩니다.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
*
*