테마 선택

📚 지식 노트

AI·하드웨어·주변기기·게임·컴퓨터 시스템·이론 컴퓨터 과학·수학·개발과 운영·보안·응용 분야에 대해 알아 두면 좋은 내용을 정리한 노트다. 위에서 분야를 고르고 아래에서 노트를 고른다.

암호

비밀을 지키고, 바뀌지 않았음을 증명하고, 누가 보냈는지 확인하는 수학적 도구다.

목차 (10)
  1. 암호가 해 주는 네 가지 일
  2. 대칭 암호: 같은 키로 잠그고 연다
  3. 블록 암호 모드: ECB를 쓰면 안 되는 이유
  4. 인증 암호(AEAD): 숨기기와 변조 검사를 한 번에
  5. 공개키 암호: RSA와 타원 곡선
  6. 해시, MAC, HMAC
  7. 키 교환: 디피–헬먼
  8. 디지털 서명과 인증서
  9. 난수: Math.random과 암호용 난수
  10. 암호는 직접 만들지 않는다

암호가 해 주는 네 가지 일

암호(cryptography)라고 하면 내용을 숨기는 일만 떠올리기 쉽지만, 실제로 쓰이는 암호 도구는 네 가지 질문에 답한다. 남이 읽을 수 있는가, 중간에 바뀌었는가, 누가 보냈는가, 보낸 사람이 나중에 아니라고 할 수 있는가. 질문마다 맞는 도구가 따로 있고, 하나로 나머지를 대신하지 못한다. 예를 들어 암호화만 하고 변조 검사를 빼면, 공격자가 내용을 읽지는 못해도 몰래 바꿀 수는 있다.

지키는 것질문도구
기밀성(confidentiality)남이 읽을 수 있는가대칭 암호, 공개키 암호
무결성(integrity)중간에 바뀌었는가해시(우연한 손상), MAC·인증 암호(일부러 바꾼 것)
인증(authentication)누가 보냈는가MAC(키를 나눈 상대), 디지털 서명(공개키의 주인)
부인 방지(non-repudiation)보낸 사람이 부정할 수 있는가디지털 서명. 키를 나눠 가진 MAC으로는 안 된다

이 목표들이 보안 전체에서 어디에 놓이는지는 보안의 기초 노트의 CIA 절에 있다. 내용을 숨기는 것과 존재 자체를 숨기는 것도 다르다. 그림 속에 글을 감추는 스테가노그래피는 들키면 그대로 읽히므로, 이미지 스테가노그래피 도구도 먼저 암호화한 뒤 숨기라고 안내한다.

대칭 암호: 같은 키로 잠그고 연다

대칭 암호(symmetric encryption)는 잠그는 키와 여는 키가 같다. 오늘날의 표준은 AES(Advanced Encryption Standard)다. 미국 NIST가 공개 공모로 여러 후보를 몇 해 동안 공격해 본 끝에 벨기에 연구자들의 Rijndael을 골라 2001년 FIPS 197로 정했다. AES는 128비트(16바이트) 블록 하나를 키에 따라 여러 라운드 섞는 블록 암호(block cipher)이고, 키 길이는 128·192·256비트 중에서 고른다.

대칭 암호는 빠르다. 요즘 CPU는 AES 전용 명령을 갖고 있어 디스크 전체 암호화나 동영상 스트리밍도 거의 부담 없이 돌린다. 약점은 키 배달이다. 두 사람이 같은 키를 갖고 있어야 하는데, 처음 만나는 상대와 그 키를 어떻게 나눌지는 대칭 암호만으로 풀 수 없다. 이 문제를 아래의 공개키 암호와 키 교환이 푼다.

대칭 암호: 평문을 키 K로 AES 암호화해 암호문을 만들고, 같은 키 K로 복호화해 평문을 되찾는다키 K평문"안녕하세요"AES 암호화키 K암호문"9f3a…"AES 복호화키 K평문"안녕하세요"AES는 128비트(16바이트) 블록 단위로 섞는다 · 키 길이는 128·192·256비트빠르지만, 두 사람이 같은 키를 미리 나눠 가져야 한다비밀 키(양쪽이 같다)같은 키가 쓰이는 곳
대칭 암호. 키 K 하나가 암호화와 복호화에 모두 쓰인다. 그래서 키를 가진 사람은 누구나 읽을 수 있고, 키를 어떻게 안전하게 나눠 주느냐가 따로 풀어야 할 문제로 남는다.

블록 암호 모드: ECB를 쓰면 안 되는 이유

AES는 16바이트 블록 하나만 다룬다. 그보다 긴 메시지를 어떻게 이어 붙여 처리할지는 운용 모드(mode of operation)가 정한다. NIST SP 800-38A가 고전적인 모드들을 정의한다.

모드방식성질
ECB(Electronic Codebook)블록마다 따로 암호화한다같은 평문 블록이 늘 같은 암호문이 된다. 무늬가 샌다
CBC(Cipher Block Chaining)앞 블록의 암호문을 다음 평문에 섞은 뒤 암호화한다. 첫 블록은 초기화 벡터(IV)와 섞는다IV는 예측할 수 없어야 한다. 변조 검사가 없다
CTR(Counter)카운터를 암호화해 만든 키 흐름을 평문에 XOR한다병렬 처리가 쉽다. 같은 키로 카운터를 다시 쓰면 안 된다. 변조 검사가 없다

ECB의 문제는 그림 하나로 드러난다. 같은 블록은 같은 암호문이 되므로, 하나하나의 값은 숨겨져도 어디가 같고 어디가 다른지라는 구조가 그대로 남는다. 그림을 ECB로 암호화하면 색은 바뀌어도 윤곽이 보이는 까닭이다. CBC처럼 앞 블록과 섞는 모드는 같은 평문 블록도 자리마다 다른 암호문이 되어 무늬가 사라진다. 라이브러리가 모드를 따로 묻는다면 ECB는 고르지 않는다.

하트 모양 평문을 블록 단위로 암호화한 결과: ECB는 같은 블록이 같은 암호문이 되어 하트가 그대로 보이고, CBC는 블록마다 값이 흩어져 모양이 사라진다평문 그림블록 하나 = 한 칸ECB로 암호화같은 블록 → 같은 암호문CBC로 암호화앞 블록과 섞여 흩어진다색 = 블록 값(0~255)을 네 구간으로 나눈 것8비트 장난감 암호로 계산한 예다. 실제 AES 블록은 128비트다
ECB와 CBC. 같은 하트 그림을 블록 하나씩 암호화했다. ECB는 같은 블록이 같은 값이 되어 하트가 그대로 보이고, CBC는 앞 블록과 섞여 모양이 흩어진다. 원리를 보이려고 8비트 장난감 암호로 계산한 그림이다.

인증 암호(AEAD): 숨기기와 변조 검사를 한 번에

CBC와 CTR은 내용을 숨기기만 한다. 공격자가 암호문의 일부 비트를 뒤집으면 받는 쪽은 바뀐 평문을 그대로 받아들이고, 복호화 오류 메시지의 차이를 이용해 내용을 알아내는 공격(패딩 오라클)까지 알려져 있다. 그래서 지금은 암호화와 변조 검사를 묶은 인증 암호(AEAD, Authenticated Encryption with Associated Data)를 기본으로 쓴다.

가장 널리 쓰이는 것은 AES-GCM(NIST SP 800-38D)과, AES 전용 명령이 없는 기기에서도 빠른 ChaCha20-Poly1305(RFC 8439)다. 둘 다 키와 논스(nonce, 한 번만 쓰는 수)를 받아 암호문과 함께 짧은 인증 태그를 낸다. 받는 쪽은 태그가 맞을 때만 평문을 돌려주고, 한 비트라도 바뀌었으면 아무것도 돌려주지 않는다. 암호화하지 않고 보호만 할 추가 데이터(패킷 헤더처럼 중간 장비가 읽어야 하는 부분)도 태그 계산에 넣을 수 있다. TLS 1.3은 이런 AEAD만 허용한다.

지켜야 할 규칙은 하나다. 같은 키로 같은 논스를 두 번 쓰지 않는다. GCM에서 논스가 겹치면 두 평문의 관계가 드러나고, 태그를 위조할 수 있는 값까지 새어 나간다. 논스는 비밀일 필요는 없어서 암호문 옆에 그대로 붙여 보내며, 메시지마다 카운터를 올리거나 충분히 긴 무작위 값을 쓴다.

AES-GCM: 키, 논스, 평문, 추가 데이터를 넣으면 암호문과 인증 태그가 나오고, 받는 쪽은 태그가 맞을 때만 평문을 돌려주며 한 비트라도 바뀌면 거부한다키 K비밀논스(nonce)메시지마다 새로평문숨길 내용추가 데이터(AAD)보이되 보호AES-GCM암호화 + 인증암호문인증 태그받는 쪽 검사태그 일치→ 평문한 비트라도 다름→ 거부평문은 숨겨지고, 추가 데이터(예: 헤더)는 보이지만 바뀌면 들킨다같은 키로 같은 논스를 두 번 쓰면 기밀성과 인증이 함께 무너진다
인증 암호(AES-GCM). 평문은 숨겨지고, 암호문·추가 데이터 어느 쪽이 바뀌어도 태그가 맞지 않아 받는 쪽이 거부한다.

공개키 암호: RSA와 타원 곡선

공개키 암호(public-key, asymmetric cryptography)는 키를 짝으로 만든다. 공개키는 누구에게 나눠 줘도 되고, 개인키는 주인만 갖는다. 공개키로 잠근 것은 개인키로만 열리고, 개인키로 서명한 것은 공개키로 누구나 확인할 수 있다. 처음 만난 상대와도 미리 비밀을 나누지 않고 안전하게 이야기를 시작할 수 있다는 점이 대칭 암호와 다르다. 기본 개념은 데이터 노트의 암호와 해시 절에도 정리되어 있다.

보내는 사람은 받는 사람의 공개키로 메시지를 잠그고, 받는 사람만 자기 개인키로 연다메시지"안녕"공개키로 잠금암호문"x9#Qa…"개인키로 열기메시지"안녕"공개키: 누구에게나 나눠 줘도 된다 (자물쇠)개인키: 받는 사람만 가진다 (열쇠)HTTPS는 이 방식으로 대칭 열쇠를 안전하게 나눈 뒤, 빠른 대칭 암호로 내용을 주고받는다
공개키 암호. 누구나 가진 공개키로 잠그고, 받는 사람만 가진 개인키로 연다.

공개키 암호의 바탕은 한쪽으로는 쉽고 반대쪽으로는 몹시 어려운 계산이다. RSA는 큰 소수 두 개를 곱하기는 쉽지만, 곱한 결과에서 두 소수를 다시 찾아내기(소인수분해)는 어렵다는 사실에 기댄다. 타원 곡선 암호(ECC, elliptic curve cryptography)는 곡선 위의 한 점을 정해진 규칙으로 여러 번 더하기는 쉽지만, 결과 점만 보고 몇 번 더했는지 알아내기(이산 로그)는 어렵다는 사실을 쓴다. 같은 안전도를 훨씬 짧은 키로 얻어서 요즘 새로 만드는 시스템은 대부분 타원 곡선을 쓴다.

방식어려운 문제대략 128비트 안전도의 키예
RSA소인수분해3072비트오래된 인증서, RSA-PSS 서명
타원 곡선타원 곡선 이산 로그256비트ECDSA·Ed25519 서명, X25519 키 교환
격자 기반(양자 내성)격자 문제수백~수천 바이트ML-KEM 키 캡슐화

공개키 연산은 대칭 암호보다 훨씬 느리다. 그래서 실제로는 공개키 암호로 대칭 키를 정하거나 서명만 하고, 내용은 AES-GCM 같은 대칭 암호로 보낸다. 앞으로 큰 양자 컴퓨터가 생기면 RSA와 타원 곡선은 모두 깨질 수 있어서, NIST는 2024년 격자 기반의 FIPS 203(ML-KEM) 같은 양자 내성 표준을 내놓았고, 브라우저와 TLS는 기존 방식과 섞어 쓰는 하이브리드 키 교환으로 옮겨 가고 있다.

해시, MAC, HMAC

암호 해시 함수(cryptographic hash function)는 어떤 길이의 데이터든 고정 길이의 지문으로 바꾼다. SHA-256(FIPS 180-4)은 256비트를 낸다. 좋은 암호 해시는 세 가지가 어렵다. 지문만 보고 원래 데이터 찾기(역상), 주어진 데이터와 지문이 같은 다른 데이터 찾기(제2 역상), 지문이 같은 아무 두 데이터 찾기(충돌)다. MD5와 SHA-1은 충돌을 실제로 만들 수 있게 되어 보안 용도로는 쓰지 않는다. 해시 테이블이 쓰는 빠른 해시는 이런 성질이 필요 없는 다른 물건이다(알고리즘의 해시 노트). 파일이나 글의 SHA-256 값은 인코딩 변환 도구에서 직접 계산해 볼 수 있다.

해시만으로는 일부러 바꾼 것을 막지 못한다. 해시는 누구나 계산할 수 있으므로, 메시지를 바꾼 사람이 새 지문을 계산해 함께 바꿔 놓으면 그만이다. 다운로드 페이지의 해시 값이 의미 있는 것은 그 값을 파일과 다른 믿을 만한 경로(HTTPS로 받은 공식 페이지)로 받았을 때뿐이다.

일부러 바꾼 것까지 잡으려면 키를 넣는다. MAC(message authentication code)은 메시지와 비밀 키로 태그를 만들어, 같은 키를 가진 상대만 태그를 만들고 확인할 수 있게 한다. 가장 흔한 것은 해시 함수로 만든 HMAC(RFC 2104)이다. 키와 메시지를 그냥 이어 붙여 해시하는 방식은 SHA-256 같은 구조에서 공격자가 메시지 끝에 내용을 덧붙이고 그에 맞는 태그까지 계산해 낼 수 있어(길이 확장) 안전하지 않고, HMAC은 키에서 만든 값을 안쪽과 바깥쪽에 한 번씩, 두 겹으로 해시하는 구조로 이를 막는다. 태그를 비교할 때는 앞에서부터 다른 곳이 나오면 바로 멈추는 일반 비교 대신, 걸리는 시간이 늘 같은 비교를 쓴다. 비밀번호 저장에는 일반 해시도 HMAC도 아닌 일부러 느린 함수를 쓴다. 그 이야기는 인증과 인가 노트에 있다.

해시와 HMAC 비교: 해시는 누구나 계산할 수 있어 메시지를 바꾼 사람도 새 지문을 붙일 수 있고, HMAC은 키 K가 있어야 맞는 태그를 만들 수 있다해시만 붙일 때메시지SHA-256지문바꾼 사람도 지문을다시 계산해 붙인다HMAC을 붙일 때메시지+ 키 KHMAC-SHA-256태그키 K가 없으면맞는 태그를 못 만든다해시는 우연한 손상(다운로드 오류)을 잡는다일부러 바꾸는 사람까지 막으려면 키가 든 MAC이나 디지털 서명이 필요하다
해시와 HMAC. 해시는 누구나 다시 계산할 수 있어 바꾼 사람이 새 지문을 붙이면 들키지 않는다. HMAC은 키 K가 없으면 맞는 태그를 만들 수 없다.

키 교환: 디피–헬먼

처음 만난 두 사람이 모두가 엿듣는 통로에서 공통 비밀 키를 정할 수 있을까. 1976년 Whitfield Diffie와 Martin Hellman이 보인 디피–헬먼 키 교환(Diffie–Hellman key exchange)이 그 방법이다. 흔한 비유는 물감이다. 두 사람은 공개된 색 하나에 각자 몰래 고른 색을 섞어 서로에게 보낸다. 받은 색에 자기 비밀 색을 한 번 더 섞으면 두 사람의 결과는 세 색을 모두 섞은 같은 색이 된다. 엿본 사람은 섞인 색 둘을 봤지만, 섞인 색에서 원래 색을 떼어 내기는 어려워 같은 색을 만들지 못한다.

수학에서는 섞기가 거듭제곱의 나머지 계산이다. 아래 그림은 p = 23처럼 작은 수로 보였지만, 실제로는 2048비트 이상의 수를 쓰거나 타원 곡선 위에서 같은 일을 한다. 오늘날 가장 흔한 것은 RFC 7748의 X25519다. 이렇게 얻은 공통 값은 그대로 쓰지 않고 HKDF 같은 키 유도 함수에 넣어 용도별 대칭 키로 뽑아낸다.

디피–헬먼 키 교환 단계 그림: 앨리스와 밥이 공개 값 p와 g에 각자 비밀을 섞은 값만 주고받아, 엿보는 이브 모르게 같은 비밀 값에 도달한다앨리스공개 통로(이브가 엿본다)밥공개: p = 23, g = 5비밀 a = 6비밀 b = 15A = 5⁶ mod 23 = 8B = 5¹⁵ mod 23 = 19이브도 8과 19를 본다19⁶ mod 23 = 28¹⁵ mod 23 = 2이브는 a·b를 몰라같은 값을 만들 수 없다두 사람만 아는 비밀 = 2공개 색(g)앨리스 비밀(a)밥 비밀(b)
1 / 6

두 사람은 공개된 수 p = 23, g = 5(공개 색)에 먼저 합의한다. 이 값은 누가 봐도 괜찮다.

디피–헬먼 키 교환. 공개 색에 각자의 비밀 색을 섞어 보내고, 받은 색에 다시 자기 비밀 색을 섞으면 두 사람의 결과가 같아진다. 숫자는 원리를 보이려는 작은 예다.

디피–헬먼에는 빈틈이 하나 있다. 상대가 정말 그 사람인지는 알려 주지 않는다. 중간의 누군가가 양쪽 모두와 따로 키 교환을 하면(중간자 공격, man-in-the-middle) 두 사람은 각자 공격자와 비밀을 나누게 된다. 그래서 실제 프로토콜은 교환한 값에 아래의 디지털 서명을 붙여 상대를 확인한다. 또 연결마다 새 비밀 수를 쓰고 끝나면 버리면, 나중에 서버의 장기 키가 새어도 지난 대화는 풀리지 않는다. 이 성질을 전방 비밀성(forward secrecy)이라 하고, TLS 1.3은 전방 비밀성이 없던 옛 키 교환 방식(정적 RSA)을 아예 없앴다. P2P 화상 통화가 쓰는 WebRTC의 DTLS-SRTP도 연결마다 이런 키 교환으로 키를 정한다.

디지털 서명과 인증서

디지털 서명(digital signature)은 공개키 암호를 거꾸로 쓴다. 보내는 사람은 문서의 해시에 개인키로 서명을 만들고, 받는 사람은 받은 문서의 해시와 보낸 사람의 공개키로 서명이 맞는지 확인한다. 맞으면 두 가지가 함께 증명된다. 이 개인키의 주인이 서명했고, 서명한 뒤로 문서가 한 비트도 바뀌지 않았다. MAC과 달리 검증하는 사람은 서명을 만들 수 없으므로, 서명한 사람이 나중에 아니라고 하기 어렵다(부인 방지). 표준 방식은 FIPS 186-5에 정리된 RSA 서명, ECDSA, EdDSA(Ed25519)다.

남은 질문은 이 공개키가 정말 그 사람 것인가다. 인증서(certificate)가 답한다. 인증서는 "이 공개키는 example.com의 것"이라는 내용에 믿을 만한 인증 기관(CA)이 서명한 문서다. 브라우저는 몇몇 루트 인증 기관의 공개키를 미리 갖고 있다가, 서버가 보낸 인증서의 서명을 따라 올라가 그 루트에 닿는지 확인한다. 이 신뢰의 사슬과 HTTPS에서의 쓰임은 네트워크 보안 노트에서 다룬다. 소프트웨어 업데이트와 패키지에 붙는 코드 서명도 같은 원리다.

디지털 서명: 보내는 쪽은 문서의 해시에 개인키로 서명해 문서와 함께 보내고, 받는 쪽은 받은 문서의 해시와 공개키로 서명을 검증해 일치하면 보낸 사람과 내용이 맞다고 판단한다보내는 쪽문서해시SHA-256서명 만들기개인키서명문서와 함께 보냄받는 쪽받은 문서해시SHA-256서명 검증공개키일치하면보낸 사람 확인 · 안 바뀜전송개인키를 가진 사람만 서명을 만들고, 공개키를 가진 누구나 검증한다인증서는 인증 기관(CA)이 "이 공개키는 이 도메인의 것"이라는 문장에 서명한 문서다
디지털 서명. 개인키로 만든 서명은 공개키로 누구나 검증할 수 있다. 문서가 바뀌면 해시가 달라져 검증이 실패하고, 개인키가 없는 사람은 맞는 서명을 만들 수 없다.

난수: Math.random과 암호용 난수

키, 논스, 세션 토큰, 비밀번호 재설정 링크는 모두 무작위 값이고, 공격자가 그 값을 맞힐 수 있으면 나머지 암호가 아무리 튼튼해도 소용없다. 컴퓨터가 내는 난수는 대부분 정해진 계산식으로 만든 의사 난수(pseudo-random)다. 게임이나 시뮬레이션용 생성기는 빠르고 고르게 퍼지는 것만 목표로 해서, 출력 몇 개로 내부 상태를 짐작하면 다음 값을 미리 계산할 수 있다. MDN의 Math.random() 문서도 이 함수가 보안 용도의 난수를 주지 않는다고 분명히 적는다.

보안에 쓰는 값은 암호학적으로 안전한 난수 생성기(CSPRNG)에서 받는다. 운영체제가 하드웨어 난수와 각종 타이밍에서 모은 엔트로피를 씨앗으로 쓰고, 앞의 출력을 모두 봐도 다음 출력을 맞힐 수 없게 설계되어 있다. 브라우저에서는 crypto.getRandomValues()가 이 생성기를 쓰고, UUID가 필요하면 crypto.randomUUID()를 쓴다. 이 사이트의 UUID·랜덤 문자열 도구도 이 함수들로 값을 만든다.

// 화면 효과: 예측되어도 상관없다
const sparkle = Math.random();

// 세션 토큰·키: 암호용 난수를 쓴다
const bytes = crypto.getRandomValues(new Uint8Array(32));
const requestId = crypto.randomUUID();
Math.random 같은 일반 난수 생성기는 작은 내부 상태에서 정해진 규칙으로 값을 내므로 출력 몇 개로 다음 값을 짐작할 수 있고, 암호용 난수 생성기는 운영체제가 모은 엔트로피를 써서 앞의 출력으로 다음 값을 맞힐 수 없다Math.random(): 일반 의사 난수작은 내부 상태정해진 규칙생성기빠른 계산식0.42 0.17 …출력출력 몇 개로 상태를짐작하면 다음이 보인다crypto.getRandomValues(): 암호용 난수(CSPRNG)OS 엔트로피하드웨어·타이밍CSPRNG암호 기본 요소9f 3a c1 …출력앞의 출력을 다 봐도다음 값을 못 맞힌다게임·시각 효과에는 Math.random()으로 충분하다키·토큰·비밀번호 재설정 링크에는 반드시 암호용 난수를 쓴다
일반 의사 난수와 암호용 난수. 둘 다 고르게 퍼진 값을 내지만, 다음 값을 맞히기 어렵다는 보장은 암호용 난수에만 있다.

암호는 직접 만들지 않는다

보안 분야의 오랜 격언은 "암호를 직접 만들지 말라(don't roll your own crypto)"다. 자기가 깨지 못하는 암호는 누구나 만들 수 있다. 어려운 것은 남들이 몇 해 동안 공격해도 깨지지 않는 암호다. 그래서 쓸 만한 알고리즘은 공개되어 있고 공개 검증을 오래 거쳤다. 알고리즘을 숨겨서 지키려 하지 말고 키만 숨기라는 원칙(케르크호프스의 원칙)은 보안의 기초 노트에 있다.

실제 사고는 알고리즘보다 그 위에서 더 자주 난다. AES를 썼어도 ECB로 쓰거나, 논스를 다시 쓰거나, 키를 소스 코드에 넣거나, 태그 비교에서 시간이 새거나, 암호화만 하고 무결성 검사를 빼면 깨진다. 검증된 라이브러리의 고수준 API는 이 결정을 대신 내려 준다. 브라우저의 Web Crypto(SubtleCrypto), 언어 표준 라이브러리의 암호 모듈, libsodium 같은 잘 알려진 라이브러리, 그리고 통신이라면 직접 짜지 말고 TLS를 쓴다. 어떤 알고리즘과 키 길이를 고를지는 OWASP의 암호 저장 치트 시트가 실무 기준을 정리해 둔다.

하려는 일고를 것피할 것
데이터 암호화AES-GCM, ChaCha20-Poly1305ECB, 인증 없는 CBC·CTR, 직접 만든 XOR 암호
무결성·출처 확인HMAC-SHA-256, Ed25519·ECDSA 서명MD5·SHA-1, 키를 이어 붙인 해시
키 교환TLS 1.3, X25519(필요하면 양자 내성 하이브리드)인증 없는 디피–헬먼
무작위 값crypto.getRandomValues(), 운영체제 CSPRNGMath.random(), 시각을 씨앗으로 쓴 난수
비밀번호 저장Argon2, scrypt, bcrypt일반 해시, 되돌릴 수 있는 암호화

그림의 키 관리 층이 실무에서 가장 자주 무너진다. 키를 만들고, 나눠 주고, 보관하고, 정기적으로 바꾸고, 폐기하는 생애주기 전체는 NIST의 SP 800-57 Part 1 Rev. 5가 다룬다. 키는 소스 코드나 설정 파일에 두지 않고, 비밀 관리 서비스나 클라우드의 키 관리 서비스(KMS), 키를 장치 밖으로 꺼내지 않고 안에서 암호 연산만 해 주는 하드웨어 보안 모듈(HSM)에 둔다. 큰 데이터는 데이터 키로 암호화하고 그 데이터 키만 KMS의 마스터 키로 다시 감싸 함께 저장하는 봉투 암호화(envelope encryption)가 흔하다. 배포 파이프라인의 비밀값 다루기는 CI/CD 노트에 있다.

흔한 오해 몇 가지.

  • "Base64로 바꿨으니 암호화했다": Base64나 URL 인코딩은 글자 표현만 바꾼 것이라 키 없이 누구나 되돌린다. JWT의 내용이 그대로 읽히는 것도 이 때문이다(인증과 인가 노트).
  • "비밀번호를 암호화해서 저장한다": 비밀번호는 되돌릴 수 있게 암호화하지 않고 느린 해시로 저장한다. 암호화는 키가 새면 모두 풀리고, 해시는 애초에 되돌릴 길이 없다.
  • "양자 컴퓨터는 먼 이야기다": 지금 엿들어 저장해 둔 암호문은 나중에 풀릴 수 있어, 오래 지켜야 할 데이터일수록 먼저 옮긴다. 영국 NCSC의 이전 일정 안내(2025)는 2028년까지 점검과 계획, 2031년까지 우선순위 높은 이전, 2035년까지 전체 이전을 목표로 제시한다. 원리는 암호학 노트에 있다.
암호 시스템의 층: 맨 아래 알고리즘은 검증되어 있고, 그 위의 모드와 논스, 키 관리, 구현, 프로토콜 조립 층에서 대부분의 실수가 생긴다프로토콜 조립암호화만 하고 무결성 검사를 빠뜨림구현비교에 걸린 시간 차이로 정보가 샘(타이밍 공격)키 관리코드에 박은 키, 짧은 비밀번호를 그대로 키로 씀모드와 논스ECB 사용, 같은 키로 논스 재사용알고리즘AES·SHA-256은 오랜 공개 검증을 거쳤다직접 짜면 위의 네 층을 혼자 다 맞혀야 한다. 고수준 API는 이 층들을 묶어서 맡는다검증된 바닥빨간 글: 흔한 실수의 예
암호가 깨지는 곳. 맨 아래의 알고리즘은 검증되어 있어도, 그 위의 모드·키 관리·구현·조립 가운데 한 곳만 틀려도 전체가 무너진다.