Post

Crypto

Crypto

Crypto

암호 기술(Cryptography)은 데이터를 안전하게 저장하고 전달하기 위해 다음 네 가지 보안 목표를 달성하는 것을 목적으로 함

보안 목표의미주요 기술
Confidentiality(기밀성)허가된 사용자만 데이터의 내용을 볼 수 있음암호화(AES, RSA)
Integrity(무결성)데이터가 중간에 변경되지 않았음을 보장Hash, MAC, 전자서명
Authentication(인증)데이터를 보낸 상대가 누구인지 확인MAC, 전자서명, 인증서
Non-repudiation(부인방지)보낸 사람이 나중에 “보내지 않았다”고 부인할 수 없음전자서명

Crypto 기술의 역할

데이터 보안 서비스

서비스기술대표 알고리즘
데이터 기밀성EncryptionAES(+RSA)
데이터 요약 / 변경 감지HASHSHA-256
메시지 인증MACHMAC
부인방지Digital SignatureRSA / DSA / ECDSA
  • AES(+RSA) : 실제로는 대용량 데이터를 빠른 대칭키(AES)로 암호화하고, 그 대칭키만 느린 비대칭키(RSA 등)로 암호화해 전달하는 하이브리드 암호화 방식을 주로 사용함

키 기반

서비스기술대표 알고리즘
난수 생성CSPRNGDRBG / OS 난수원
키 쌍 생성Key Pair GenerationRSA, EC(P-256)
키 합의Key AgreementDH, ECDH
키 유도KDFHKDF, PBKDF2
Public Key의 소유자 인증CertificateX.509
  • 데이터 보안 서비스는 결국 키를 기반으로 동작하므로, 키를 안전하게 만들고(생성), 나누고(합의), 파생시키고(유도), 신뢰할 수 있게(인증서) 하는 기술이 함께 필요함

대칭키 & AES

대칭키 암호화

  • 암호화와 복호화에 동일한 Secret Key를 사용하는 방식
1
2
3
           Secret Key                     Secret Key
               │                              │
Plaintext ─▶ [암호화] ─▶ Ciphertext ─▶ [복호화] ─▶ Plaintext
  • 장점 : 연산이 빠르고 대용량 데이터 암호화에 적합함
  • 단점 : 송신자와 수신자가 같은 키를 미리 안전하게 공유해야 함 (키 분배 문제)
    • N명이 서로 1:1로 통신하려면 N(N-1)/2개의 키가 필요해 키 관리가 어려움
    • 이 문제를 해결하기 위해 비대칭키, DH/ECDH 같은 키 합의 기술을 함께 사용함
  • 종류
    • Block Cipher : 데이터를 고정 크기 블록 단위로 암호화 (AES, DES, ARIA, SEED)
    • Stream Cipher : 데이터를 비트/바이트 단위로 Key Stream과 XOR해서 암호화 (ChaCha20)

왜 N(N-1)/2개의 키가 필요할까?

  • 모든 사람이 같은 키 하나를 쓰면 A가 B에게 보낸 메시지를 C도 복호화할 수 있음
    • A와 B 사이의 비밀을 지키려면 A-B만 아는 키가 따로 있어야 함
    • 즉, 두 사람마다 서로 다른 키가 하나씩 필요함 → 키 개수 = N명 중 2명을 고르는 경우의 수
  • 계산
    • 한 사람은 자기를 제외한 N-1명과 각각 키가 필요함
    • N명 × (N-1)개로 세면 A-B 키와 B-A 키를 두 번 센 것이므로(같은 키) 2로 나눔
1
N(N-1) / 2  =  N명 중 2명을 고르는 조합 nC2
  • 예시 (N = 4)
1
2
3
4
5
      A
    / | \
   B──┼──C        키 : A-B, A-C, A-D, B-C, B-D, C-D
    \ | /         → 4 × 3 / 2 = 6개
      D
사용자 수(N)대칭키 개수 N(N-1)/2비대칭키 개수 2N
468
104520
1004,950200
1,000499,5002,000
  • 대칭키는 사용자가 늘어날수록 키 개수가 N²에 비례해 증가하므로 키 분배, 보관, 교체 부담이 커짐
  • 비대칭키는 각자 공개키 1개 + 개인키 1개만 가지면 됨
    • 누구에게 보내든 받는 사람의 공개키로 암호화하면 되므로 전체 키는 2N개

AES(Advanced Encryption Standard)

  • 대표적인 대칭키 Block Cipher로, 2001년 NIST가 DES를 대체하는 표준으로 채택함 (원래 이름 : Rijndael)
  • Block Size : 128bit(16byte)
  • Key Size에 따라 라운드 수가 달라짐
구분Key SizeRound 수
AES-128128bit10
AES-192192bit12
AES-256256bit14
  • Round
    • 암호 알고리즘 내에서 암호화할 데이터 블록을 여러 번 반복적으로 변환하는 과정
    • 라운드 수가 많을수록 암호 알고리즘 강도는 높아지며 이를 통해 공격에 대한 저항성이 높아짐

AES 동작 과정

  1. 16byte 평문 블록을 4x4 바이트 행렬(State)로 배치함
  2. Key Expansion : 원래의 Key로부터 각 라운드에서 사용할 Round Key들을 생성함
  3. 초기 라운드 : AddRoundKey
  4. 반복 라운드 (AES-128 기준 9번) : 아래 4단계를 순서대로 수행
    • SubBytes : S-Box 테이블을 이용해 각 바이트를 다른 바이트로 치환 (비선형성 → 혼돈, Confusion)
    • ShiftRows : 각 행을 0, 1, 2, 3칸씩 왼쪽으로 회전 이동
    • MixColumns : 각 열을 행렬 곱셈으로 섞음 (ShiftRows와 함께 → 확산, Diffusion)
    • AddRoundKey : State와 Round Key를 XOR
  5. 마지막 라운드 : MixColumns를 제외한 SubBytes → ShiftRows → AddRoundKey
  6. 최종 State가 Ciphertext가 됨
  • 복호화는 각 단계의 역연산(InvSubBytes, InvShiftRows, InvMixColumns)을 역순으로 수행함

혼돈(Confusion) : 키와 암호문의 관계를 복잡하게 만듦 확산(Diffusion) : 평문 1bit의 변화가 암호문 전체에 퍼지도록 만듦

블록 암호 운용 모드(Mode of Operation)

  • AES는 한 번에 16byte만 암호화할 수 있으므로, 16byte보다 긴 데이터를 암호화하려면 블록들을 어떻게 연결할지 정해야 함 → 운용 모드
  • 평문 길이가 블록 크기의 배수가 아니면 패딩(Padding, 주로 PKCS#7)이 필요한 모드(ECB, CBC)와 필요 없는 모드(CTR, GCM, CCM)가 있음

AES-ECB(Electronic Code Book)

  • 각 Plaintext Block을 독립적으로 암호화
1
2
3
4
5
   P1          P2          P3
   │           │           │
[AES(K)]    [AES(K)]    [AES(K)]
   │           │           │
   C1          C2          C3
  • Ci = E(K, Pi)
  • 장점 : 구조가 단순하고 블록별 병렬 처리가 가능함
  • 단점 : 같은 평문 블록은 항상 같은 암호문 블록이 되어 평문의 패턴이 그대로 드러남
    • 이미지를 ECB로 암호화하면 윤곽이 그대로 보이는 “ECB 펭귄” 예시가 유명함
  • 보안상 실제 데이터 암호화에는 사용하지 않음

AES-CBC(Cipher Block Chaining)

  • 이전 Ciphertext를 다음 Block에 사용
  • 첫 블록은 이전 암호문이 없으므로 IV(Initialization Vector)를 사용함
1
2
3
4
5
6
7
        P1             P2             P3
        │              │              │
IV ───▶(⊕)     ┌─────▶(⊕)     ┌─────▶(⊕)
        │      │       │      │       │
     [AES(K)]  │    [AES(K)]  │    [AES(K)]
        │      │       │      │       │
        C1 ────┘       C2 ────┘       C3
  • 암호화 : Ci = E(K, Pi ⊕ Ci-1), C0 = IV
  • 복호화 : Pi = D(K, Ci) ⊕ Ci-1
  • 장점 : 같은 평문 블록이라도 앞 블록이 다르면 다른 암호문이 됨
  • 단점
    • 암호화는 이전 블록 결과가 필요하므로 병렬 처리 불가 (복호화는 병렬 가능)
    • 패딩이 필요하고, 패딩 오류 응답을 이용한 Padding Oracle 공격에 취약할 수 있음
    • 무결성을 보장하지 않으므로 별도의 MAC이 필요함
  • IV는 매번 예측 불가능한 랜덤 값을 사용해야 함

AES-CTR(Counter)

  • Plaintext를 직접 AES에 넣지 않고 Nonce + Counter를 AES로 암호화하여 Key Stream 생성
  • 생성한 Key Stream과 Plaintext를 XOR해서 Ciphertext를 만듦 → 블록 암호를 스트림 암호처럼 사용
1
2
3
4
5
6
7
Nonce||Ctr1   Nonce||Ctr2   Nonce||Ctr3
    │             │             │
 [AES(K)]      [AES(K)]      [AES(K)]
    │ Key Stream  │             │
P1─(⊕)        P2─(⊕)        P3─(⊕)
    │             │             │
    C1            C2            C3
  • 암호화 : Ci = Pi ⊕ E(K, Nonce || Counter_i)
  • 복호화 : Pi = Ci ⊕ E(K, Nonce || Counter_i) → 암호화와 복호화가 같은 연산 (AES 복호화 함수가 필요 없음)
  • 장점
    • 블록끼리 독립적이어서 암호화/복호화 모두 병렬 처리 가능
    • XOR만 하므로 패딩이 필요 없음
  • 단점
    • 같은 Key에서 Nonce + Counter를 재사용하면 안 됨 : 같은 Key Stream이 나와 C1 ⊕ C2 = P1 ⊕ P2가 되어 평문이 노출됨
    • 무결성을 보장하지 않음 (암호문 비트를 뒤집으면 평문의 같은 위치 비트가 뒤집힘)

AES-GCM(Galois/Counter Mode)

  • Encryption과 Authentication을 함께 제공하는 AEAD(Authenticated Encryption with Associated Data) 모드
    • CTR 모드로 암호화 + GHASH(Galois Field 곱셈 기반 해시)로 인증 태그 생성
  • 입력 : Key, IV(Nonce, 보통 96bit), Plaintext, AAD(Additional Authenticated Data)
    • AAD : 암호화하지는 않지만 변조되면 안 되는 데이터 (예: 패킷 헤더)
  • 출력 : Ciphertext, Authentication Tag(보통 128bit)

암호화 과정

  1. H = E(K, 0^128) : 0 블록을 AES로 암호화해 GHASH용 해시 키를 생성
  2. IV로 초기 카운터 블록 J0를 만듦
  3. J0 + 1부터 시작하는 카운터로 CTR 모드 암호화 수행 → Ciphertext
  4. GHASH(H, AAD, Ciphertext)를 계산하고, 그 결과를 E(K, J0)와 XOR → Tag
  • Decryption은 Verification을 함께 수행
    • 수신자는 받은 AAD와 Ciphertext로 Tag를 다시 계산해 받은 Tag와 비교함
    • Tag가 다르면 복호화 결과를 내보내지 않고 실패 처리함
  • 장점 : 빠르고 병렬 처리가 가능함. TLS 1.3, IPSec 등에서 가장 많이 사용됨
  • 주의 : CTR과 마찬가지로 같은 Key에서 IV를 재사용하면 기밀성뿐 아니라 인증까지 깨짐

AES-CCM(Counter with CBC-MAC)

  • CTR + CBC-MAC 구조의 AEAD 모드
    • CBC-MAC으로 인증 태그 생성 + CTR 모드로 암호화
  • 입력 : Key, Nonce(7~13byte), Plaintext, AAD

암호화 과정

  1. Nonce, 메시지 길이 등으로 첫 블록 B0를 만듦
  2. B0 || AAD || Plaintext를 CBC-MAC으로 계산해 Tag T를 생성 (IV = 0인 CBC 암호화의 마지막 블록)
  3. Counter 블록 A1, A2, ...로 CTR 모드 암호화해 Ciphertext 생성
  4. Counter 블록 A0로 만든 Key Stream과 T를 XOR해 최종 Tag 생성
  • 복호화 시에는 CTR로 평문과 Tag를 복원한 뒤, 평문으로 CBC-MAC을 다시 계산해 Tag를 비교함
  • 장점 : AES 암호화 함수 하나만으로 구현 가능해 하드웨어/임베디드 환경에 적합함
  • 단점 : CBC-MAC 계산과 CTR 암호화로 데이터를 두 번 처리하고, CBC-MAC은 병렬 처리가 불가능해 GCM보다 느림
  • 사용 예 : Wi-Fi(WPA2 CCMP), Bluetooth LE, Zigbee, IEEE 1609.2(V2X)의 AES-128-CCM

운용 모드 비교

모드패딩병렬 암호화무결성비고
ECB필요OX패턴 노출, 사용 금지
CBC필요XXIV 필요
CTR불필요OXNonce 재사용 금지
GCM불필요OOAEAD, 가장 널리 사용
CCM불필요XOAEAD, 임베디드/V2X

Hash / SHA-256 / HMAC

HASH

  • 임의 길이 입력을 고정 길이 HASH 값(Digest)으로 변환하는 단방향 함수
  • 데이터 무결성 확인 시 사용
    • 파일 다운로드 후 배포자가 공개한 해시값과 비교해 변조 여부 확인
    • 전자서명 시 메시지 전체 대신 해시값에 서명
    • 비밀번호 저장 (단, 단순 해시가 아니라 Salt + KDF 사용)
  • 암호학적 해시 함수의 조건
성질의미
역상 저항성(Preimage Resistance)해시값 h가 주어졌을 때 H(m) = h인 m을 찾기 어려움
제2 역상 저항성(Second Preimage Resistance)m1이 주어졌을 때 H(m1) = H(m2)인 다른 m2를 찾기 어려움
충돌 저항성(Collision Resistance)H(m1) = H(m2)인 서로 다른 m1, m2 쌍을 찾기 어려움
  • 눈사태 효과(Avalanche Effect) : 입력이 1bit만 바뀌어도 출력의 약 절반이 바뀜
  • MD5, SHA-1은 충돌이 발견되어 보안 용도로 더 이상 사용하지 않음

SHA-256(Secure Hash Algorithm)

  • NIST에서 표준화한 SHA-2 계열의 해시 함수
  • 입력 길이와 관계없이 출력은 256bit
    • 256bit = 32byte
    • 16진수 표현 시 64자리
1
2
SHA-256("abc")
= ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

SHA-256 동작 과정 (Merkle–Damgård 구조)

  1. Padding : 메시지 뒤에 1 비트를 붙이고, 전체 길이가 512bit의 배수가 되도록 0을 채운 뒤, 마지막 64bit에 원래 메시지 길이를 기록함
  2. Block 분할 : 패딩된 메시지를 512bit(64byte) 블록으로 나눔
  3. 초기 해시값 설정 : 32bit 초기값 8개(H0 ~ H7)를 준비함
  4. 압축 함수(Compression) : 블록마다 아래 과정을 반복
    • 512bit 블록을 32bit 워드 16개로 나누고, 이를 확장해 64개의 워드(Message Schedule)를 만듦
    • 8개의 작업 변수(a~h)를 현재 해시값으로 초기화하고, 64라운드 동안 비트 연산(회전, 시프트, XOR, AND, 덧셈)과 라운드 상수를 이용해 섞음
    • 결과를 현재 해시값에 더해 다음 블록의 입력으로 사용함
  5. 마지막 블록까지 처리한 후 H0 ~ H7(32bit x 8 = 256bit)을 이어 붙인 것이 최종 해시값
1
2
3
IV(H0~H7) ─▶ [압축 f] ─▶ [압축 f] ─▶ ... ─▶ [압축 f] ─▶ Hash
                ▲           ▲                   ▲
             Block 1     Block 2             Block N

Merkle–Damgård 구조는 H(m)과 m의 길이만 알면 비밀값을 몰라도 H(m || 추가 데이터)를 계산할 수 있는 Length Extension 공격에 취약함. 그래서 H(Key || Message) 형태로 MAC을 만들면 안 되고 HMAC을 사용해야 함

HMAC(Hash-based Message Authentication Code)

  • Hash 함수와 Secret Key를 사용하여 메시지 인증 코드를 생성하는 방식
  • 단순 Hash는 누구나 계산할 수 있어 공격자가 메시지를 바꾸고 해시도 다시 계산할 수 있음
    • HMAC은 Secret Key를 아는 사람만 올바른 값을 만들 수 있으므로 무결성 + 메시지 인증을 함께 제공함

HMAC 동작 과정

1
HMAC(K, m) = H( (K' ⊕ opad) || H( (K' ⊕ ipad) || m ) )
  1. Key를 Hash의 블록 크기(SHA-256은 64byte)에 맞춤 → K'
    • Key가 블록 크기보다 길면 해시하고, 짧으면 뒤에 0을 채움
  2. Inner Hash : K' ⊕ ipad(0x36 반복)와 메시지를 이어 붙여 해시
  3. Outer Hash : K' ⊕ opad(0x5c 반복)와 Inner Hash 결과를 이어 붙여 다시 해시
  4. 최종 결과가 HMAC 값 (HMAC-SHA256은 32byte)
  • 해시를 두 번 감싸는 구조 때문에 Length Extension 공격에 안전함

HMAC 검증 과정

  1. 송신자 : 메시지와 HMAC(K, m)을 함께 전송
  2. 수신자 : 같은 Key로 받은 메시지의 HMAC을 다시 계산
  3. 받은 값과 비교해 같으면 변조되지 않았고, Key를 가진 상대가 보냈다고 판단
    • 비교 시 타이밍 공격을 막기 위해 상수 시간 비교(Constant-time Compare)를 사용해야 함

HMAC은 송신자와 수신자가 같은 Key를 공유하므로 수신자도 같은 HMAC을 만들 수 있음. 따라서 제3자에게 “누가 만들었는지” 증명할 수 없어 부인방지는 제공하지 못함 → 부인방지가 필요하면 전자서명을 사용함

비대칭키 / RSA / DSA / ECDSA

비대칭키

  • 서로 다른 두 개의 Key 사용
    • Public Key(공개키) : 누구에게나 공개
    • Private Key(개인키) : 소유자만 보관
  • 두 키는 수학적으로 연결되어 있지만, 공개키로부터 개인키를 계산하는 것은 사실상 불가능함
    • RSA : 큰 수의 소인수분해 문제
    • DSA, DH : 이산 로그 문제
    • ECC(ECDSA, ECDH) : 타원 곡선 이산 로그 문제
  • 사용 방식은 목적에 따라 두 가지
목적송신자수신자제공하는 보안
암호화수신자의 공개키로 암호화자신의 개인키로 복호화기밀성
전자서명자신의 개인키로 서명송신자의 공개키로 검증무결성, 인증, 부인방지
  • 장점 : 키 분배 문제 해결 (공개키는 공개해도 됨), 전자서명 가능
  • 단점 : 대칭키보다 연산이 수백~수천 배 느림 → 데이터 암호화는 대칭키로, 키 교환과 서명은 비대칭키로 하는 하이브리드 방식을 사용함

RSA - Rivest, Shamir, Adleman

  • 1977년 세 사람의 이름을 따서 만든 최초의 실용적인 공개키 알고리즘
  • 암호화와 전자서명 모두 가능함
  • 안전성 : 두 큰 소수의 곱 n을 다시 소인수분해하기 어렵다는 점에 기반

키 생성 과정

  1. 두 개의 큰 소수 p, q를 선택
  2. n = p × q 계산 (n의 비트 수가 키 길이, 예: 2048bit)
  3. φ(n) = (p - 1)(q - 1) 계산
  4. φ(n)과 서로소인 공개 지수 e 선택 (보통 65537)
  5. e × d ≡ 1 (mod φ(n))을 만족하는 개인 지수 d 계산
  6. 공개키 : (n, e), 개인키 : (n, d)

암호화 / 복호화

  • 암호화 : C = M^e mod n
  • 복호화 : M = C^d mod n

작은 수 예시

1
2
3
4
5
6
7
8
9
p = 61, q = 53
n = 61 × 53 = 3233
φ(n) = 60 × 52 = 3120
e = 17
d = 2753  (17 × 2753 = 46801 = 15 × 3120 + 1)

M = 65
암호화 : C = 65^17 mod 3233 = 2790
복호화 : M = 2790^2753 mod 3233 = 65

서명 / 검증

  • 서명 : S = H(M)^d mod n (개인키 사용)
  • 검증 : S^e mod n을 계산해 H(M)과 같은지 비교 (공개키 사용)

  • 실제로는 위의 수식을 그대로 쓰면(Textbook RSA) 안전하지 않아 패딩을 함께 사용함
    • 암호화 : RSA-OAEP
    • 서명 : RSA-PSS (또는 PKCS#1 v1.5)
  • 키 길이 : 현재 최소 2048bit 이상 권장

Digital Signature

  • 본인 증명을 위해 서명하는 수단
  • 손으로 하는 서명처럼, 메시지를 개인키를 가진 사람만 만들 수 있는 값으로 서명하고, 누구나 공개키로 확인할 수 있게 함
  • 제공하는 보안 : 무결성, 인증, 부인방지

서명 / 검증 과정

1
2
3
4
5
6
7
8
9
[송신자]
Message ─▶ Hash ─▶ Digest ─▶ [서명(개인키)] ─▶ Signature
                                                   │
                         Message + Signature 전송  │
                                                   ▼
[수신자]
Message ─▶ Hash ─▶ Digest ──────┐
                                ├─▶ 비교 / 검증 ─▶ 성공 or 실패
Signature ─▶ [검증(공개키)] ─────┘
  1. 송신자는 메시지를 해시해 Digest를 만듦 (메시지 전체가 아닌 고정 길이 값에 서명하므로 빠름)
  2. Digest를 자신의 개인키로 서명해 Signature를 만들고 메시지와 함께 전송
  3. 수신자는 받은 메시지를 같은 해시 함수로 해시함
  4. 송신자의 공개키로 Signature를 검증해 Digest와 일치하는지 확인
    • 일치 : 메시지가 변조되지 않았고(무결성), 해당 개인키 소유자가 서명했음(인증, 부인방지)
    • 불일치 : 메시지 변조 또는 다른 사람이 서명함

전자서명은 공개키가 정말 그 사람의 것인지 확인할 수 있어야 의미가 있음 → 이를 보장하는 것이 인증서(X.509)

DSA(Digital Signature Algorithm)

  • NIST가 전자서명 전용으로 표준화한 알고리즘 (DSS, FIPS 186)
  • RSA와 달리 서명만 가능하고 암호화는 불가능함
  • 안전성 : 이산 로그 문제 (g^x mod p에서 x를 구하기 어려움)

키 생성

  1. 공개 파라미터 : 큰 소수 p, p - 1의 소인수 q, 생성자 g
  2. 개인키 : 랜덤 값 x (0 < x < q)
  3. 공개키 : y = g^x mod p

서명 과정

  1. 서명마다 새로운 랜덤 값 k 선택 (0 < k < q)
  2. r = (g^k mod p) mod q
  3. s = k^-1 × (H(m) + x × r) mod q
  4. 서명 값 : (r, s)

검증 과정

  1. w = s^-1 mod q
  2. u1 = H(m) × w mod q, u2 = r × w mod q
  3. v = (g^u1 × y^u2 mod p) mod q
  4. v == r 이면 검증 성공

서명할 때 사용하는 k가 재사용되거나 예측 가능하면 서명 두 개로 개인키 x를 계산할 수 있음 (Sony PS3 서명 키 유출 사례). DSA/ECDSA는 k를 반드시 안전한 난수로 생성하거나 RFC 6979의 결정적 방식으로 생성해야 함

  • 현재는 키와 서명 크기가 더 작은 ECDSA로 대부분 대체되었고, FIPS 186-5(2023)에서는 새로운 서명 생성용으로 DSA를 더 이상 승인하지 않음

ECDSA(Elliptic Curve Digital Signature Algorithm)

  • 타원 곡선 암호(ECC)를 이용하는 Digital Signature Algorithm
  • DSA를 타원 곡선 위의 연산으로 옮긴 것

타원 곡선 암호(ECC)

  • 타원 곡선 y² = x³ + ax + b (mod p) 위의 점들로 연산함
  • Scalar Multiplication : 점 G를 d번 더하는 연산 Q = d × G
    • d와 G로 Q를 계산하는 것은 쉽지만, Q와 G로 d를 구하는 것은 매우 어려움 (ECDLP)
  • 같은 보안 강도에서 RSA보다 키가 훨씬 짧아 연산이 빠르고 저장 공간이 적음
보안 강도RSA 키 길이ECC 키 길이
128bit3072bit256bit (P-256)
192bit7680bit384bit (P-384)
256bit15360bit521bit (P-521)

키 생성

  • 공개 파라미터 : 곡선, 기준점 G, G의 위수 n
  • 개인키 : 랜덤 정수 d (1 ≤ d ≤ n - 1)
  • 공개키 : 곡선 위의 점 Q = d × G

서명 과정

  1. z = H(m) (메시지 해시)
  2. 랜덤 값 k 선택 (1 ≤ k ≤ n - 1)
  3. 점 (x1, y1) = k × G 계산
  4. r = x1 mod n (0이면 k를 다시 선택)
  5. s = k^-1 × (z + r × d) mod n (0이면 k를 다시 선택)
  6. 서명 값 : (r, s)

검증 과정

  1. z = H(m)
  2. w = s^-1 mod n
  3. u1 = z × w mod n, u2 = r × w mod n
  4. 점 (x1, y1) = u1 × G + u2 × Q 계산
  5. r == x1 mod n 이면 검증 성공
  • P-256 기준 서명 크기는 r, s 각 32byte로 총 64byte
  • V2X(IEEE 1609.2)에서는 차량이 초당 수많은 메시지를 서명·검증해야 하고 메시지 크기도 작아야 하므로, 서명이 작고 빠른 ECDSA(NIST P-256, brainpoolP256r1 등)를 사용함

Key Generation & Key Establishment

Key Generation

  • 암호 알고리즘에 필요한 Secret Key 또는 Public/Private Key Pair를 생성하는 과정
  • 키의 안전성은 난수의 품질에 달려 있음
    • 일반 난수(rand() 등)는 예측 가능하므로 반드시 CSPRNG(Cryptographically Secure PRNG)를 사용해야 함
    • DRBG : NIST SP 800-90A에서 정의한 결정적 난수 생성기 (CTR_DRBG, Hash_DRBG, HMAC_DRBG)
    • OS 난수원 : /dev/urandom, getrandom(), Windows BCryptGenRandom 등
  • 알고리즘별 키 생성 방식
종류생성 방식
대칭키(AES)CSPRNG로 128/256bit 랜덤 값 생성
RSA큰 소수 p, q를 랜덤으로 생성 후 n, e, d 계산
EC(P-256)랜덤 정수 d 생성 후 Q = d × G 계산
  • 생성한 개인키는 HSM(Hardware Security Module)이나 보안 칩에 저장해 외부로 노출되지 않도록 관리함

Key Establishment

  • 통신하는 두 당사자가 같은 Secret Key를 갖도록 하는 과정
    • Key Transport : 한쪽이 키를 만들어 상대 공개키로 암호화해 전달 (예: RSA 키 전송)
    • Key Agreement : 양쪽이 값을 교환해 같은 키를 각자 계산 (예: DH, ECDH)

DH(Diffie-Hellman)

  • 공개된 통신 채널을 통해 서로의 공개값을 교환하여 동일한 Shared Secret을 계산하는 방식
  • Secret Key 자체는 네트워크로 전송되지 않음

동작 과정

  1. A와 B가 공개 파라미터 소수 p와 생성자 g를 공유함
  2. A는 비밀값 a를 선택하고 A = g^a mod p를 B에게 전송
  3. B는 비밀값 b를 선택하고 B = g^b mod p를 A에게 전송
  4. A는 S = B^a mod p, B는 S = A^b mod p를 계산
  5. 두 값은 g^(ab) mod p로 동일함 → Shared Secret
1
2
3
4
5
6
7
p = 23, g = 5

A : a = 4  →  A = 5^4 mod 23 = 4   ──▶  B에게 전송
B : b = 3  →  B = 5^3 mod 23 = 10  ──▶  A에게 전송

A : S = 10^4 mod 23 = 18
B : S = 4^3  mod 23 = 18   →  Shared Secret = 18
  • 공격자는 p, g, A, B를 볼 수 있지만 a나 b를 알아내려면 이산 로그 문제를 풀어야 함
  • 주의 : DH 자체에는 상대방 인증 기능이 없어 중간자 공격(MITM)에 취약함
    • 공격자가 중간에서 A, B와 각각 DH를 수행할 수 있음
    • 그래서 교환하는 공개값에 전자서명을 하거나 인증서로 상대를 확인함
  • 매 세션마다 새로운 비밀값을 사용(Ephemeral DH, DHE)하면 나중에 장기 키가 유출되어도 과거 통신을 복호화할 수 없음 → 전방향 안전성(Forward Secrecy)

ECDH(Elliptic Curve Diffie-Hellman)

  • 타원곡선의 Scalar Multiplication을 이용하여 동일한 Shared Secret을 계산하는 Key Agreement 방식
  • DH와 원리는 같고, 거듭제곱 대신 타원 곡선의 Scalar Multiplication을 사용함

동작 과정

  1. A와 B가 같은 곡선과 기준점 G를 사용함
  2. A : 개인키 dA, 공개키 QA = dA × G → B에게 전송
  3. B : 개인키 dB, 공개키 QB = dB × G → A에게 전송
  4. A는 S = dA × QB, B는 S = dB × QA를 계산
  5. 두 값은 dA × dB × G로 동일함 → Shared Secret (보통 점의 x좌표 사용)
  • 계산된 Shared Secret을 그대로 키로 쓰지 않고 KDF(HKDF 등)를 거쳐 실제 암호화 키를 만듦
  • DH보다 짧은 키로 같은 보안 강도를 제공해 TLS 1.3의 기본 키 교환 방식(ECDHE)으로 사용됨
  • V2X(IEEE 1609.2)에서는 ECDH 기반의 ECIES로 AES-CCM 대칭키를 수신자의 공개키로 암호화해 전달함

HKDF(HMAC-based Key Derivation Function)

  • 기존의 비밀값으로부터 암호학적으로 사용할 Key를 도출하기 위한 HMAC 기반 KDF (RFC 5869)
  • DH/ECDH의 Shared Secret처럼 길이가 맞지 않거나 균일하게 랜덤하지 않은 값을 안전한 키로 바꿔줌
  • 하나의 비밀값으로 용도별(암호화 키, MAC 키, IV 등)로 서로 다른 여러 키를 만들 수 있음

동작 과정 (Extract-then-Expand)

  1. Extract : 입력 비밀값(IKM)을 Salt와 함께 HMAC해 고정 길이의 균일한 키(PRK)를 만듦
    • PRK = HMAC(Salt, IKM)
  2. Expand : PRK와 info(용도를 구분하는 문자열)를 이용해 필요한 길이만큼 키(OKM)를 늘림
    • T(1) = HMAC(PRK, info || 0x01)
    • T(2) = HMAC(PRK, T(1) || info || 0x02)
    • …
    • OKM = T(1) || T(2) || ...의 앞에서 필요한 길이(L)만큼 사용
  • info를 다르게 주면 같은 PRK에서 서로 독립적인 키를 만들 수 있음 (예: "client key", "server key")
  • TLS 1.3, Signal 프로토콜 등에서 키 스케줄에 사용함

PBKDF2(Password-Based Key Derivation Function 2)

  • Password와 Salt를 입력받아 HMAC 등의 연산을 반복 수행함으로써 암호키를 도출하는 방식 (RFC 8018)
  • 비밀번호는 사람이 기억할 수 있는 값이라 엔트로피가 낮음 → 반복 연산으로 계산을 일부러 느리게 만들어 무차별 대입 공격을 어렵게 함
1
DK = PBKDF2(PRF, Password, Salt, Iterations, dkLen)

동작 과정

  1. 출력 키 길이(dkLen)만큼 블록 T1, T2, ...을 만듦
  2. 각 블록 Ti는 다음과 같이 계산
    • U1 = HMAC(Password, Salt || INT(i))
    • U2 = HMAC(Password, U1)
    • …
    • Uc = HMAC(Password, Uc-1) (c = 반복 횟수)
    • Ti = U1 ⊕ U2 ⊕ ... ⊕ Uc
  3. DK = T1 || T2 || ...의 앞에서 dkLen만큼 사용
  • Salt : 사용자마다 다른 랜덤 값을 섞어 같은 비밀번호라도 다른 키가 나오게 함 → 레인보우 테이블 공격 방지
  • Iterations : 반복 횟수가 클수록 공격 비용이 커짐 (OWASP 권장 : PBKDF2-HMAC-SHA256 기준 600,000회)
  • GPU를 이용한 병렬 공격에 상대적으로 약해, 메모리를 많이 쓰는 scrypt, Argon2가 대안으로 사용됨
구분HKDFPBKDF2
입력이미 랜덤성이 높은 비밀값 (DH 결과 등)엔트로피가 낮은 비밀번호
목적키 추출 및 확장무차별 대입을 어렵게 만들기
속도빠름의도적으로 느림

X.509

  • 공개 키 기반(PKI)의 디지털 인증서 표준 (ITU-T X.509, 인터넷용 프로파일 RFC 5280)
  • 인증서는 “이 공개키는 이 주체의 것이다”라는 내용을 신뢰할 수 있는 인증기관(CA)이 전자서명으로 보증한 문서
  • 역할
    • 공개 키 인증 : 공개키와 해당 키 소유자 간의 관계를 인증
    • 디지털 서명 : 개인 키로 디지털 서명을 생성하고, 공개 키로 서명을 확인
    • 데이터 암호화 : 공개 키로 데이터를 암호화하고, 개인키로 복호화
    • 통신 보안 : SSL/TLS와 같은 프로토콜에서 신원 확인 및 암호화 통신을 가능하게 함

X.509 v3 인증서 구조

필드설명
Version인증서 버전 (현재 v3)
Serial NumberCA가 발급한 인증서 고유 번호
Signature AlgorithmCA가 서명에 사용한 알고리즘 (예: sha256WithRSAEncryption, ecdsa-with-SHA256)
Issuer인증서를 발급한 CA
Validity유효 기간 (Not Before ~ Not After)
Subject인증서 소유자
Subject Public Key Info소유자의 공개키와 알고리즘
ExtensionsKey Usage, Basic Constraints(CA 여부), SAN(도메인 목록) 등
Signature Value위 내용을 해시해 CA 개인키로 서명한 값
  • ASN.1로 정의되고 DER로 인코딩됨 (텍스트로 저장할 때는 Base64로 변환한 PEM 형식 사용)
  • 폐기된 인증서는 CRL(인증서 폐기 목록)이나 OCSP(실시간 상태 조회)로 확인함

V2X에서는 X.509 대신 크기가 더 작고 빠르게 처리할 수 있는 IEEE 1609.2 인증서를 사용하며, OER로 인코딩함

Certificate Chain of Trust

1
2
3
4
5
6
7
Root CA Certificate          (Self-Signed, OS/브라우저 Trust Store에 미리 설치)
        │ 서명
        ▼
Intermediate CA Certificate  (Root CA의 개인키로 서명)
        │ 서명
        ▼
End-Entity Certificate       (Intermediate CA의 개인키로 서명, 서버/기기의 인증서)
  • End-Entity Certificate : 실제 서버나 기기의 인증서
  • Intermediate CA Certificate : Root CA 대신 실제로 인증서를 발급하는 중간 인증기관의 인증서
  • Root CA Certificate : 신뢰의 출발점. 스스로 서명한(Self-Signed) 인증서로, 미리 Trust Store에 설치되어 있음

검증 과정

  1. 서버가 End-Entity 인증서와 Intermediate CA 인증서를 함께 전달함
  2. End-Entity 인증서의 서명을 Intermediate CA의 공개키로 검증함
  3. Intermediate CA 인증서의 서명을 Root CA의 공개키로 검증함
  4. Root CA가 Trust Store에 있으면 체인 전체를 신뢰함
  5. 각 인증서의 유효 기간, 폐기 여부, 용도(Key Usage), 도메인(SAN) 등도 함께 확인함
  • Intermediate CA를 두는 이유
    • Root CA의 개인키가 유출되면 체인 전체를 신뢰할 수 없게 되므로, Root CA는 오프라인으로 안전하게 보관함
    • 평소 발급은 Intermediate CA가 담당하고, Intermediate CA가 문제가 생기면 해당 CA만 폐기하면 됨
This post is licensed under CC BY 4.0 by the author.