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

HYEONG HWAN, MUN/ 11월 8, 2022/ 미분류/ 4 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진법을(2의 4승; 2^4) 사용하는 hex 를 주로 사용한다.
1Byte 는 8Bit 이다 (2^8). 따라서 2개의 hex 값을 사용해서 1개의 Byte를 표시한다. 두개의 hex의 결합; (2^4 * 2^4)
예를 들어 32Byte 를 hex로 표현하면 2배인 64글자가 된다. (SHA256 은 32BIT 이므로, DB 설계시 CHAR(64) 또는 VARCHAR(64)로 정의해야 한다.)

 

- Hexa-decimal 을 사용하는 이유
Byte 의 범위는 0 ~ 255 이다. 아스키 코드표는 non printable character 가 있어서 사람이 인지하기에 부적절 했다. (눈으로 보고 무결성 검사 불가능)
따라서 사람이 인식할 수 있는(human readable, printable) 문자로의 변환이 필요로 했고, hexa-decimal(0123456789abcdef)이 채택되었다.

물론 사람의 인지가 필요 없는 경우에는 Byte 자체를 저장할 수도 있다. (MYSQL 에서는 data type를 BLOB로 설정하여 저장함.)

 

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 -

NIST(National Institute of Standards and Technology)와 NSA(National Security Agency)는 미국 정부의 두 개의 다른 기관입니다. 각각의 기관은 고유한 목적과 역할을 갖고 있습니다.

NIST는 미국 상업 부문과 관련된 기술 및 측정 표준을 개발하고 유지하는 데 중점을 둔 물리학 연구소입니다. NIST는 공인된 표준, 테스트 및 인증 프로그램을 제공하여 기술 및 측정 분야에서 높은 신뢰성과 신뢰성을 유지하기 위해 노력합니다. 이를 통해 산업과 기타 조직들은 제품의 품질, 안전성 및 호환성을 보장할 수 있습니다. NIST는 공개적이고 중립적인 기관으로 알려져 있으며, 공공 및 사설 부문을 대상으로 기술 및 표준 개발을 수행합니다.

반면에 NSA는 미국의 정보 보안 및 외교 정보 기관으로, 미국 국방부의 하부 기관입니다. NSA는 외교, 국방 및 국가 안보 관련 정보 수집, 분석 및 암호 해독에 관여합니다. 주요 임무는 통신과 정보 시스템의 보안을 유지하고, 미국의 정보 및 통신 시스템을 보호하며, 국가 안보 목적을 위해 정보를 수집하고 분석하는 것입니다. NSA는 국가 안보 및 국방 기관으로서의 비밀 유지와 기밀 정보 보호에 초점을 둡니다.

NIST와 NSA는 때때로 협력하고 정보를 교환할 수 있지만, 두 기관은 주로 다른 목적과 역할을 수행합니다. NIST는 기술 및 측정 표준을 개발하고 유지함으로써 산업 및 공공 부문에 신뢰성과 효율성을 제공하며, NSA는 정보 수집, 암호 해독 및 국가 안보를 담당합니다.

NSA는 국정원 같은 곳이고, NIST 는 KISA 같은 곳입니다. 아무튼 2023년 현재 NIST 에서는 (NSA에서 개발한)SHA256 을 권장하고 있습니다.
(NIST의 가이드라인을 따르면 됨.)

 

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

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

 

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

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

TIP : SHA3 써보는 것은 추천한다. 하지만 신규 소프트웨어 프로젝트에서 SHA3를 (굳이) 선택하지는 말아라.

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

TIP : SHA256 은 현재 비트코인 작업증명에서 사용하고 있다.

 

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

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

비밀번호는 암호화 함수 쓰면 안되고 해시함수(또는 비슷한 이론의 함수)를 사용해야 합니다.

 

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

SHA256의 문제점이 아닙니다. 비밀번호 암호화 관점에서의 해시 함수는 다음의 2가지 중요한 문제가 있습니다.

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

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

 

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

 

Encryption

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

1) 받는 쪽에서 원본 메세지를 확인해야 하는 경우
2) 네트워크 중간에서 노출되었을때 해석이 불가능 해야함

소프트웨어적으로 원본 문자열을 정해진 규칙으로 변조해야 한다.

Unauthorized User 가 암호화키를 볼 수 없을 경우 => AES 를 주로 사용. RSA 사용하는 경우도 있음.
Unauthorized User 가 암호화키를 볼 수 있는 경우 => 비 대칭키 암호화 방식인 RSA 사용.

RSA는 메세지 크기 제약도 있고, CPU도 더 많이 사용하고 다루기 어렵다. 적절한 암호화 방식을 사용할 것.

 

나는 업무상 개인정보를 다룰 일이 많은데, 위의 그림은 어느 업체에게 전달한 회원정보 연동 도식도이다. (PPT로 그린건데, 원본파일은 회사 PC에 있는듯하다.)
대기업의 경우, DB에서 개인정보를 추출하는 사람과, 대외기관에 전달하는 사람다르기 때문에 역할에 맞게 적절히 암호화가 되어있어야 한다.
즉, 대외계 담당자는 개인정보에 접근할 수 없어야 한다.

그리고 원본 메세지를 확인할 수 있어야 하기 때문에 Encryption 을 사용해야 하며, AES-256-CBC 알고리즘을 선택하였다.

 

AES 알고리즘

AES(Advanced Encryption Standard)는 현재 가장 널리 사용되는 암호화 알고리즘 중 하나입니다. AES는 대칭키 알고리즘이며, 데이터를 암호화하고 복호화하기 위해 동일한 키를 사용합니다. AES는 다양한 키 길이와 암호화 모드를 지원하며, 다음과 같은 세 가지 주요 종류가 있습니다:

AES-128: 128비트 키를 사용하는 AES입니다. 데이터 블록 크기는 128비트(16바이트)이며, 암호화 키로 128비트 키를 사용합니다.

AES-192: 192비트 키를 사용하는 AES입니다. 데이터 블록 크기는 128비트(16바이트)이며, 암호화 키로 192비트 키를 사용합니다.

AES-256: 256비트 키를 사용하는 AES입니다. 데이터 블록 크기는 128비트(16바이트)이며, 암호화 키로 256비트 키를 사용합니다. AES-256은 가장 강력한 보안 수준을 제공합니다.

이 세 가지 종류의 AES는 대부분의 암호화 요구에 충분한 수준의 보안을 제공합니다. 암호화 키의 길이가 더 길어질수록 암호화의 강도가 증가하지만, 처리 속도가 느려질 수 있습니다. 따라서 암호화 알고리즘을 선택할 때는 보안 요구 사항과 성능 요소를 고려해야 합니다.

 

AES 알고리즘 종류

  1. AES-256-CBC (Cipher Block Chaining):
    AES-256-CBC는 “Cipher Block Chaining”의 약자로, 암호화된 이전 블록과 현재 블록을 XOR 연산하여 다음 블록을 암호화하는 방식입니다. CBC 모드에서는 초기화 벡터(Initialization Vector, IV)라는 무작위의 값이 필요합니다. CBC 모드는 각 블록이 이전 블록의 암호문에 의존하기 때문에, 데이터 블록 사이에 상호 연관성을 도입하여 더 안전한 암호화를 제공합니다. CBC 모드는 암호화와 복호화에 IV를 사용하며, 동일한 IV를 사용하는 것은 보안에 취약할 수 있습니다.
  2. AES-256-ECB (Electronic Codebook):
    AES-256-ECB는 “Electronic Codebook”의 약자로, 각 데이터 블록을 독립적으로 암호화하는 방식입니다. ECB 모드는 동일한 평문 블록에 대해 항상 동일한 암호문 블록을 생성합니다. 이는 암호화된 이미지나 패턴이 뚜렷하게 드러나는 “암호문 패턴”을 생성할 수 있으며, 보안에 취약한 모드로 알려져 있습니다. 따라서 ECB 모드는 반복되는 패턴이나 구조가 없는 데이터에 적합하지만, 보안 요구사항이 높은 경우에는 권장되지 않습니다.

일반적으로 AES-256-CBC가 AES-256-ECB보다 더 안전한 암호화 방식으로 간주됩니다. CBC 모드는 이전 블록의 암호문에 의존하므로 패턴이 존재하지 않고, 데이터 무결성을 제공하기 위해 추가적인 보안 기법인 MAC(Message Authentication Code)을 사용할 수 있습니다.

ECB는 원본 메세지에 대해서 고정된 결과물을 생성한다. 해시함수인 SHA와 유사하지만 Encryption 함수이기 때문에 SHA와 달리 복호화가 된다.

CBC는 랜덤 백터인 IV를 생성하고 그것으로 암호화를 시작한다. 암호화된 메세지 뿐만 아니라, IV도 전송되어야 하므로 메세지가 더 길어진다. IV는 암호화된 메세지 앞에 붙이거나, 뒤에 붙이거나 기타 여러방식으로 전달한다. 만약 IV를 고정된 값으로 사용하면 ECB처럼 고정된 암호화 결과물이 생성된다.
(많은 프로젝트에서 고정된 IV를 사용하는 것을 확인하였다. 대기업 프로젝트도 이런 경우 많더라. 주로 사용하는 IV 값은 0x30 ~ 0x39 반복(또는 0x31 ~ 0x30 반복). )

 

RSA 알고리즘

RSA(Rivest-Shamir-Adleman) 알고리즘은 공개키 암호화와 디지털 서명에 사용되는 암호화 알고리즘입니다. RSA 알고리즘은 1977년에 로널드 라이베스트(Ron Rivest), 아디 샤미르(Adi Shamir), 레오네르드 아들만(Leonard Adleman)에 의해 개발되었습니다.

RSA는 두 개의 대칭성을 갖는 키 쌍인 공개키와 개인키를 사용합니다. 공개키는 누구나 알 수 있고, 개인키는 암호화 및 복호화 뿐만 아니라 디지털 서명에 사용되는 비밀 키입니다.

RSA 알고리즘은 공개키 암호화와 디지털 서명을 위해 널리 사용되며, 안전성과 수학적 기반이 강한 알고리즘으로 알려져 있습니다. 하지만 RSA 알고리즘은 계산량이 많고 긴 키 길이를 사용해야 하므로, 대칭키 암호화에 비해 처리 속도가 상대적으로 느립니다.

Public Key로 암호화 하고 Private Key로 복호화 하는 것과, Private Key 로 signature를 생성하고 Public Key로 verify 하는 것이 있습니다.
둘 다 실습해 볼 것을 강력하게 추천합니다. (encryption/decryption, sign/verify 실습 해보지 않고 RSA 잘한다고 말하지 말 것.)

 

RSA 알고리즘 종류

  1. RSA 2048
  2. RSA 3072
  3. RSA 4096

일반적으로 RSA 키 길이는 1024비트(거의 안씀), 2048비트, 3072비트, 4096비트 등과 같은 8의 배수로 정의됩니다.

RSA 2048은 현재 많은 애플리케이션에서 권장되는 키 길이로 간주되며, 대부분의 보안 요구사항을 충족합니다. RSA 2048 비트 키는 현재로서는 충분한 안전성을 제공하며, 일반적으로 국가 기밀 및 상용 보안에 사용되는 수준으로 인정받고 있습니다.

2023년 현재, 1024 비트는 거의 사용되지 않으며, 4096비트는 오버스팩이고, 주로 2048비트를 많이 사용합니다.
하지만 요즘 RSA 3072를 권장하는 추세입니다. 따라서 신규 프로젝트에서는 RSA 3072를 사용하는 것을 권장합니다. (미래에 하드웨어 발전으로 인해 위협이 생길 가능성을 미리 차단함)
Apple Mac 의 경우 SSH keygen 시의 RSA 비트가 RSA 2048 에서 RSA 3072 로 바뀌었습니다.

RSA 768 : 안전하지 않음. (2009년 12월)
RSA 829 : 안전하지 않음. (2020년 2월)
RSA 1024 : 현재 안전함. 10년 후에도 안전할지는 불확실
RSA 2048 : 현재 안전함. 100년 후에도 안전할지는 불확실
RSA 3072 : 하드웨어의 발전 속도가 일정하다고 가정했을 경우, 100년 후에도 안전


 

실전 예제

지금까지 암호화에 대한 이론에 대해서 알아 보았고, 이제 실제 코드 예제를 살펴보도록 합다.

예제는 Login Auth 및 DB Store 입니다.

 

실제 코드 예제는 준비중..

 

- 난독화

 

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

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

 

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

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

 

 


더 알아보기

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

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

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

 

비밀번호

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

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

 

 

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

키 스트레칭 방법은 암호화를 여러 번 실행하여 공격자로 하여금 비밀번호를 쉽게 알아내지 못하도록 방지하는 방법이다. 보안은 여러 개의 보안 방법을 같이 쓰면 좋아지니 salt와 키 스트레칭을 같이 사용하는 것이 좋다.

 

레인보우테이블

 

브루트포스

 

알고리즘 종류

선택

 

코드 예제

pbkdf2-sha256

 

봉투 암호화

 

4 Comments

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

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

  2. 정성들여 작성해 주신 글 정말 잘 읽었습니다!!
    하나 궁금한 점이 생겨서 질문드립니다.
    내용중에 “비밀번호 해시함수는 적절히 느려야 한다. sha512 보다 sha256 을 사용할 것!” 이라고 적어주신 내용에 대한 추가적인 설명을 해주실 수 있나요? 비밀번호 해시함수가 적절히 느려야 된다는 내용이 어떤 의미인지 모르겠어서요

    1. 비밀번호 해시함수가 빠르면 무작위 대입공격이 쉬워집니다.
      sha512 보다 sha256이 50% 정도 느립니다.

HYEONG HWAN, MUN에 답글 남기기 응답 취소

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

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>
*
*