모드 설명 특징
ECB (Electronic Codebook) 동일한 평문 블록이 항상 같은 암호문 블록으로 변환됨 간단하고 빠름
CBC (Cipher Block Chaining) 이전 암호문 블록을 XOR하여 암호화 패턴 숨김 가능, 보안 강화
CFB (Cipher Feedback) 암호문 일부를 피드백하여 스트림처럼 동작 메시지 크기 제한 없음
OFB (Output Feedback) 내부 상태를 이용한 스트림 모드 에러 전파 없음, 동기화 가능
CTR (Counter Mode) 증가하는 카운터 값을 암호화하여 XOR 병렬 처리 가능, 성능 우수
GCM (Galois/Counter Mode) CTR 기반으로 인증 기능 추가 무결성 검증(AEAD 지원), 빠름
XTS (XEX-based Tweaked CodeBook mode with CipherText Stealing) 디스크 암호화에 특화됨 특정 크기 데이터 보호에 적합

사용하면 안 되는 AES 모드

  1. ECB (Electronic Codebook)
    • 동일한 입력이 동일한 출력으로 변환되므로 패턴이 보존됨보안 취약
    • 예제: 이미지 암호화 시 패턴이 남음 (펭귄 이미지 문제)
  2. OFB (Output Feedback) 및 CFB (Cipher Feedback)
    • IV를 재사용하면 키 스트림이 반복되어 보안이 깨질 위험이 있음
    • 동기화 문제가 발생할 경우 전체 데이터가 손상될 가능성 존재

추천하는 AES 모드

  1. GCM (Galois/Counter Mode)
    • AEAD (Authenticated Encryption with Associated Data) 지원
    • 무결성 검증 기능 포함 → 데이터 변조 감지 가능
    • 빠른 속도와 병렬 처리 가능
    • TLS 1.2/1.3에서 가장 많이 사용됨
  2. CTR (Counter Mode)
    • 빠르고 병렬화 가능
    • IV(Nonce) 관리만 잘하면 안전
  3. XTS (XEX-based Tweaked CodeBook mode with CipherText Stealing)
    • 디스크 암호화용으로 가장 적합
    • BitLocker, APFS 등에서 사용

'PKI' 카테고리의 다른 글

[PQC] 격자 기반 전자 서명 테스트(java24)  (0) 2025.03.19
ECIES-X963-SHA256-AESGCM  (0) 2025.03.17
[EC] 디지털 서명 3종  (0) 2025.03.16
[양자내성암호] Kyber 찍먹해보기  (0) 2025.02.20
전자서명(pkcs#7)과 전자봉투  (0) 2019.12.22

새롭게 출시된 JAVA24에서 PQC를 지원한다.

CRYSTALS-Dilithium(ML-DSA)를 지원한다고 해서 테스트를 해보았다. FALCON(FN-DSA)는 아직 미지원인듯 하다.

파라미터 공개키 개인키 서명
ML-DSA-44 1312 2560 2420
ML-DSA-65 1952 4032 3309
ML-DSA-87 2592 4896 4627
package org.example

import java.security.KeyPair
import java.security.KeyPairGenerator
import java.security.Signature

fun main() {
    // ML-DSA 키 쌍 생성
    val keyGen = KeyPairGenerator.getInstance("ML-DSA-44")
    val keyPair: KeyPair = keyGen.generateKeyPair()

    // 개인키 & 공개키 원본 데이터 및 크기 출력
    val privateKeyBytes = keyPair.private.encoded
    val publicKeyBytes = keyPair.public.encoded

    println("Private Key (Raw Bytes): ${privateKeyBytes.joinToString(" ") { "%02X".format(it) }}")
    println("Private Key Size: ${privateKeyBytes.size} bytes")

    println("Public Key (Raw Bytes): ${publicKeyBytes.joinToString(" ") { "%02X".format(it) }}")
    println("Public Key Size: ${publicKeyBytes.size} bytes")

    // 메시지 서명
    val signature = Signature.getInstance("ML-DSA")
    signature.initSign(keyPair.private)
    val message = "Quantum-Secure Message".toByteArray()
    signature.update(message)
    val signedMessage: ByteArray = signature.sign()

    // 서명 데이터 원본 및 크기 출력
    println("Signature (Raw Bytes): ${signedMessage.joinToString(" ") { "%02X".format(it) }}")
    println("Signature Size: ${signedMessage.size} bytes")

    // 서명 검증
    signature.initVerify(keyPair.public)
    signature.update(message)
    val isValid: Boolean = signature.verify(signedMessage)

    println("Signature Valid: $isValid")
}
Private Key (Raw Bytes): 30 82 0A 18 02 01 00 30 0B 06 09 60 86 48 01 65 03 04 03 11 04 82 0A 04 04 82 0A 00 43 53 FD 67 AE 49 30 DE 92 DE E1 CE AB AB 10 AA 88 4A CC 48 8D 70 CE 32 42 C8 71 5B 70 8A 25 11 39 14 FE 92 F3 9B F7 68 06 58 5D CE 57 DC 16 D6 AE 12 41 52 30 7D F0 72 AB FE DE 85 61 4B 0A 19 29 F8 A5 E1 67 38 78 04 EF 7E 6E 16 31 BE 98 09 77 58 5B 37 C2 AB 52 28 97 42 FF 52 D5 D8 DE CD 07 95 37 2A 03 14 2B 4D D6 CB EB 6C 2A CA 72 0C 80 F7 27 86 0B 5C CB 96 D5 16 63 E2 BE F4 61 4B 11 A5 30 61 42 26 1C 37 41 99 84 08 D9 06 72 62 C4 8C 03 41 85 5B 30 65 88 32 69 DC 90 25 D9 22 40 02 93 11 81 82 21 1C 22 8D 4B 12 2C 11 48 82 89 14 24 23 38 24 48 C8 40 1C C7 28 DA 02 44 CA 92 80 0A 17 30 92 28 71 5A 26 65 8A 20 50 01 12 09 04 41 45 CC 94 08 01 93 60 14 C7 2C 83 96 01 10 89 81 82 94 8C 02 28 62 52 42 02 1B 08 24 0B 13 29 D9 12 51 1B 10 11 53 00 31 0A B0 24 1A A7 8D 98 B2 4C 1B 94 68 20 84 2D A0 10 82 01 96 09 9A 28 30 0A 19 2E 10 02 49 14 88 69 1C 40 28 44 34 69 21 87 65 63 06 30 11 89 90 53 B2 49 0C 80 45 1A 16 65 00 A4 50 1A 41 8D 1A C5 50 0B 38 8E 0A 42 10 5A B4 2C 5A 42 6E D9 B2 8D C1 00 66 DB 14 8C E0 38 26 C1 A0 69 93 A8 65 20 98 2D 80 C0 08 54 30 46 54 C6 91 42 B6 6D 0A 83 60 9C 96 21 E3 02 50 08 24 8C C2 16 21 14 C7 45 80 34 69 51 20 88 00 43 8E 1A C6 60 0C B5 24 E4 04 10 C4 30 82 0B 07 28 18 48 69 CB 90 69 02 38 26 60 48 12 92 38 52 0B 25 88 4A 22 21 C8 26 91 49 16 4E 01 28 09 23 A8 6D 10 93 08 49 22 0C 04 10 30 91 18 86 13 48 09 24 27 48 92 02 52 A2 C0 10 92 16 84 08 34 90 20 B2 50 E0 16 61 0B 01 80 40 32 00 11 21 81 0A 28 69 4B 80 11 9C 34 2C A2 90 90 01 17 09 18 B4 31 58 84 90 22 18 92 41 A6 88 1C 08 8A 4A 86 69 43 44 70 14 19 08 9C 34 4C 24 28 21 9C 86 45 53 24 49 5A 30 2C 20 B6 41 A0 20 06 13 83 50 E3 12 44 90 10 02 C2 A2 09 23 14 06 9C 36 6A DB 30 09 0C 09 02 23 B5 41 12 98 69 5B A2 01 9A 26 64 4B 28 68 C9 00 08 0A 17 89 C9 36 06 09 00 00 D8 20 10 10 18 41 E2 38 04 54 10 70 DA 38 32 9C 04 90 63 48 0D 08 32 72 53 B0 8D 22 49 90 4C 42 25 82 14 25 1C 46 61 0A 41 22 1A 35 2C 02 24 61 11 12 8D 11 29 10 08 94 30 22 27 46 CB 30 49 04 C3 6C 18 C2 91 0A 42 61 C4 C4 09 E4 A8 88 80 26 22 9C 36 0C D4 24 60 98 90 6C 20 80 61 CB 32 29 E1 86 51 1B 38 82 E2 82 29 44 42 2C 04 C3 31 40 04 2D 42 30 09 23 26 85 23 B8 20 22 99 28 D3 A8 68 21 A5 49 E3 B0 71 04 87 04 14 04 49 13 45 89 58 36 48 8A C0 8C 21 47 21 21 04 40 44 B0 6D CC C2 84 C9 04 80 64 82 31 D0 02 86 94 08 4A 09 05 80 1A C3 8C C1 12 31 CC 96 05 24 81 20 53 A6 09 9B 88 01 D9 86 89 98 36 91 8A 26 64 A3 02 4E 22 08 51 40 B0 50 C4 C2 71 52 20 45 80 90 6D 18 B6 81 CC 88 20 C4 28 71 12 16 0E A2 22 25 09 04 50 14 31 51 D3 46 01 22 82 71 48 44 70 02 A0 30 24 85 48 11 08 04 4C 28 20 24 05 0A 5B 04 28 DA 14 00 21 45 42 89 94 31 12 A4 01 A1 06 6C CB 96 31 9A 06 50 A2 30 06 1A 34 09 5C 06 42 C2 28 48 01 41 CE 83 4B 0A A8 56 C8 4A 97 9C F3 CB 35 49 09 73 EB 1C E8 87 62 CB D5 5D D0 62 D5 40 7C 23 69 97 29 1D BF D4 09 9A C5 95 C6 E3 A6 CE FC 04 68 C6 1E 5B 66 C1 DD 0E 70 23 F1 31 77 28 5F 91 1E AE 23 9A 73 96 B0 72 2C D8 89 9C 31 00 40 54 3F A5 86 56 08 50 1F 00 6F EA C6 CB 54 7A C8 5E 75 3D A5 5B 35 EC 0E DE CB 3C 09 E7 E5 F1 31 D4 9E 33 C3 E7 86 3A 26 63 53 4A DB FB 4B 15 A7 C9 82 6D B9 36 A4 64 D7 BC C1 36 53 09 1A D9 95 80 72 92 6A DB E8 EC 12 40 E3 68 BA 41 30 FC 05 FF BA 67 C5 2D B4 32 A1 3F 39 FD 46 E2 2B 7A 8D EB 01 63 08 27 7D 92 16 57 1A 74 54 DC F3 5C 07 C2 CB 38 CF B8 44 FC 7E 07 98 ED 65 12 58 DD C1 EB 1D 67 F1 38 4D 34 7D 47 F9 A9 16 5D F2 A7 05 23 C9 15 08 86 AC F1 CD B5 BB 1C C3 30 07 EC 88 14 C3 01 24 23 C3 9D 8C D9 DF E2 EB 08 06 B0 A5 24 9F FD 4C 0B AE 0A AE A9 70 DE 64 03 85 E6 29 EE 45 17 69 17 D4 EF 6B EA E9 4B EB C9 A9 BE C7 02 1C 8A 1F 79 40 49 32 D7 83 29 DA 49 73 8D 5B 7F 36 89 41 73 63 3C E8 B3 AD 96 31 B0 A1 C6 05 06 C6 D0 86 FC 44 35 82 CC 50 24 B8 B3 34 AA D3 82 E5 99 A9 5C DC 02 AD 00 92 F8 EA 4E 9E F3 02 CA 6C 9C E3 72 36 47 0C 5A 64 FD 39 33 79 22 38 7B EC 74 55 CB E8 A1 22 D1 5A 4E 32 28 08 FF 86 58 7E 6A 83 2B 10 6F D5 E0 EE 02 6D 22 4A BC 80 BD 95 AA AF 2D C1 DC 51 76 F4 8D 6B 5F 83 25 D8 B7 47 B9 5B D2 4E E2 43 9B 5E 0E 3D 51 C6 EA EC EE 86 6D CC 91 3C 81 0B C3 40 DA 1E 8E D7 88 AC AA BD EA 1D 79 72 DA 45 CB AE 1D 2B 69 B2 B2 3D 66 B4 41 17 DE 91 E5 ED 2F 67 82 58 BF 1D F4 68 D5 01 DA A2 A9 71 4D 7F ED DD 0E A6 B4 02 3C D9 2A FE 7D 9F DB 0D 09 94 B9 9F 00 56 84 3A 03 9B 72 F7 04 1D CD 7A 8A E7 C2 BD A4 4D 4A 9E DC 23 7D C8 78 43 59 0B C4 A3 F9 72 1C 75 46 97 86 FD AC 7E 16 86 FD 4B 8F AD 64 7B E9 A4 30 29 75 18 C8 6D BF DA 1E AC 28 3D 69 8C F7 16 A0 24 7F 00 52 D7 BF 9C DC 5D 92 20 AE C4 B8 4B 27 99 F8 32 B2 42 F9 5E A3 7F 2F 2C 47 3A DD 53 04 F1 83 C2 B9 E9 48 5B EA 49 41 BB 82 D0 19 51 50 CB FC 85 52 C3 97 12 9D B6 82 49 95 8B AB 6C 84 64 E6 ED 65 96 74 74 49 4F 4C 5F B8 9A A8 F0 2A 25 BF 1E 05 59 E0 4D F1 EA 9D 6D 2C A6 88 41 E1 95 90 18 66 D3 1E 5A 4E 39 71 B6 3E E3 1F 2B B6 0E 56 A0 4B 58 49 CB 19 28 83 7E 64 9A 7E DD 19 56 CD 2F 4B 6E A4 90 39 3B 4E 56 16 D2 FA AD 6D F0 9A 82 53 FF 57 82 A9 1A AB 6E AE 3B 21 9B 30 5C 20 39 EA 99 6C E4 F4 9C 9E 35 4C 68 6B 6F 8A 41 28 5C B1 3B 4C E6 F2 C6 11 21 A8 4E 2F C8 70 73 3B 11 35 05 4F E5 9D DB 8A 63 20 60 33 17 58 D6 59 57 ED 5B 8F DB 50 60 05 D9 D1 3C 6F BE 30 84 08 1C 42 65 0E 17 8B 5B CD 71 FD 82 04 E2 F5 02 76 64 E7 58 4C AD B4 74 8F 80 DD DA D2 1F 30 68 69 B2 C8 A8 FD 5C 70 69 CB 42 2B 94 11 23 0E 73 B9 0D F8 FA 37 0A 20 D9 DA 9A C8 CF D4 E3 9D AB 8F CC 0D 52 B4 8E 3D FC 73 C0 5A 04 6C 0E 68 64 02 92 45 DB 8E 2B D0 35 2B 08 73 19 DC 58 60 62 AE 32 A4 87 DB 85 D2 44 0C 74 93 3D A8 61 CF E6 80 FB 51 39 C5 29 61 59 C9 43 61 47 65 17 49 86 D3 E0 A4 AB 94 F4 6C 8A 40 8C 94 E2 34 0F 96 55 7D B2 76 81 15 7F 35 26 11 F9 22 40 77 B8 7A 51 A8 EC BC 32 13 E2 2E 10 0F A2 AC 53 26 49 4C 27 F7 50 04 18 8C 57 CC 57 C6 F4 5D E1 72 38 8E 90 26 F3 8E 96 39 8C 5F C6 80 FA E5 B0 C3 5F 4B AD 44 92 18 1E 80 15 B2 30 7E 75 27 06 B8 07 E3 DF 08 71 55 50 F8 C4 0A D5 97 B5 9C 8B 50 A9 07 B7 43 BF 8C 29 C8 06 06 B7 BC B7 B2 18 EB 8E 70 03 7F 20 93 21 AF BA FA 15 73 F0 BC F9 76 3D 13 CD 30 D2 99 E6 E0 CA E6 DA 2A 42 E9 DB 56 BB B6 05 10 90 85 E2 E5 3F 22 B9 FD 3A 97 E7 9E 5F D9 FB 6C FF C8 C6 5F 4D 30 EA 63 83 AF 1A 8B 82 5F 6D 80 49 D2 9A F5 25 B7 39 53 4A 57 21 33 0E 20 6F 30 F5 6B BE 39 88 60 8B 2B BC BF 30 3D DA ED B4 1F 95 47 FF 26 7D 9F 5C 19 D6 38 29 3E 89 77 E8 EF 70 11 A9 80 44 24 D9 B3 97 97 ED 16 BE CF 41 85 A6 91 6B 69 44 34 D4 AB 1E 21 75 32 E7 5E DA 55 43 A1 A7 88 F0 58 FD 65 25 1D BA 46 9D 6D 95 42 90 63 B8 C4 6E 26 AD 7C 55 8C BB C8 69 15 E1 3E BB CF 12 2F 57 B7 F5 E0 82 31 9C B7 45 0C 6E 5A 50 B6 CD F6 ED FD 99 AF 0D 21 81 32 80 02 D7 6F 13 56 F0 FA 07 EE 3D A3 12 05 4E 87 FC 0D 19 44 BF 30 49 23 83 D4 73 F5 4B D4 0A 2B 29 EB 45 D2 6F 86 C8 DC A0 1A 75 90 35 7A 0D A7 C3 D1 E3 5E B0 AB 74 0F 6F C0 38 26 95 A5 70 8A 41 82 DC 88 83 BA 22 6A 84 B5 43 EE 2E C5 89 38 13 8C 73 5F F6 DF F2 3F A5 4D A9 58 2D D5 12 22 C5 19 5D 8E D4 43 86 51 06 4D 7F FC A6 CD 32 E5 88 AC E9 2D 46 10 D5 30 5D 03 86 E5 66 24 01 71 00 AE 75 CE B0 62 8C EA 3F EB C3 EE 77 44 68 E5 91 F1 E5 88 6C A7 22 1A 1E 69 F1 3F A1 C2 7E B3 75 58 B5 E4 ED 20 C7 F9 96 26 CB 05 94 60 9E 35 1F 0C F5 D6 3F 17 3A 81 3D 33 E4 BF 17 91 35 D6 DC D5 11 02 92 1F C7 6B 0E 12 8D 11 0F E9 D1 A7 77 D7 E4 6F 00 43 CB F5 D8 51 3C F0 AC 52 29 32 5B CA 92 D0 F7 4A E3 C6 EC 51 79 CD CC 61 E5 78 25 62 43 5E 8A E8 8B 56 D8 1C AD 0F 01 52 50 AD B3 38 44 E7 61 42 B7 02 69 DB 38 C5 22 19 0B 6F 34 7D BD 8A 69 AF 96 B0 B7 D5 21 8D 79 44 4C 3D 95 5A D5 95 0D 10 AA 37 57 C2 90 26 32 73 7A BC 80 8C AD 50 5C 23 81 6D 93 FB D1 A0 12 D0 0B BE 55 9B 6B F2 BB 0F FA FC A5 A6 D8 B0 98 85 C9 FB 05 76 DF F7 5E 10 B2 DA 88 CA 9D C4 D0 33 A1 09 37 76 C8 DA 14 65 FF 38 77 11 A0 C2 FE 7B B7 10 55 EE B5 38 96 E5 EE AC 45 B6 6F 88 79 0E 9B 40 5B 81 85 19 68 52 02 F2 5E A7 06 83 03 6D 9C 38 E1 C1 F4 EC 51 EC
Private Key Size: 2588 bytes
Public Key (Raw Bytes): 30 82 05 32 30 0B 06 09 60 86 48 01 65 03 04 03 11 03 82 05 21 00 43 53 FD 67 AE 49 30 DE 92 DE E1 CE AB AB 10 AA 88 4A CC 48 8D 70 CE 32 42 C8 71 5B 70 8A 25 11 1F D3 6C 80 7A DD 05 44 D5 70 7C 95 C9 52 E0 9A A9 E2 FB C7 C8 97 75 56 EB 23 8E 9E C0 AB A7 24 FC 3C C3 62 0A C7 CF 7F 79 3B 73 4F D7 81 0A 74 9D C0 B5 54 09 84 D0 01 00 4E B5 41 89 D9 08 7E BE EA E3 6A 5B 0F C9 38 A4 17 FD 37 34 6A 79 1F 4A 57 4F 28 78 FF BA 6C C7 3F 69 AB 75 DA 6A 8A BD 61 CC 4E F8 B4 28 36 1F 5A 4C 92 82 A9 49 10 51 6C 0E A7 90 C6 3D 8D 52 5C 1F A4 BD 05 0E BF 2E C0 0A D7 16 6A 7C CA E6 28 AB 2A 9A 7E E7 75 05 25 EF 23 4F 2E 93 AD 4F B4 F6 7B D1 15 75 53 27 27 83 01 E0 0C E7 D8 74 CE 9D C8 B7 42 25 7D 2F D6 C8 D7 3A 18 8B E5 74 79 20 13 8B E2 8B D0 04 54 67 18 3A E9 0F 90 6A C6 2D 39 D9 C4 AD 35 EF FA BA A4 CA BF B5 D1 83 A7 28 B4 E9 F8 E3 2C 68 1B 9C CD 5C E2 38 9A EA E9 C1 27 5A F6 43 BF 79 C3 2D 70 DB 64 09 D4 0B 6F 4C 65 A5 0A A9 59 62 44 1E B2 06 02 17 69 7E 41 95 66 A8 2C D4 1C E0 69 34 DC CF 8A 04 35 69 1F F6 5F FA 59 B8 54 AA BD 7A EC 5F B8 F5 A3 5F 93 A4 9D F6 31 80 C2 10 BE 75 02 4C 3D 94 D2 0F C9 04 2A 3C E4 C9 82 C9 2B B3 3E 12 C4 2A 09 82 E3 B4 0E 28 95 BC F4 AD DB B9 22 7C 0F 77 B5 B5 0E F2 9F CF 87 42 5E BD 41 D2 9F DD DA 03 9F 48 DA B5 C8 D3 41 88 A2 D5 F2 9F FD 2E 72 4F F6 79 75 3F A7 3F 22 D5 AA 22 74 00 52 25 6F 3C 72 02 54 3C C3 F5 13 31 DC 7D 9B B4 56 DB C8 9D C3 23 90 93 F7 6D 3E 32 94 05 6B 73 06 0F EF 9A 83 5E 46 F9 76 48 D6 8A F1 A9 B3 36 42 D0 97 17 E0 29 BF B8 1A BF 6E 68 DD 45 39 8E 6B 54 76 35 50 AF 83 7F 7A 97 63 2B 41 96 ED FF EF 35 43 6F 63 BE DA DC D1 C9 17 9F C3 E7 3D 6C FF 38 56 23 EA 94 21 42 BF EC A5 75 83 2C 0B 59 46 7A B8 D4 93 1D 7D 42 DD 53 B3 88 8D 14 AE 50 4C 14 2D 0E 30 EF 09 0E 8C 32 FE 02 29 39 A2 0E 7E 9A FB D4 23 4F F7 E2 31 1C 65 4D 24 1D 6C 5C A7 2A 8F 07 BA B7 3B 9A 8D 68 F2 D1 EE 28 FA 8E E1 AC 69 64 E1 DB 52 29 BB 30 E6 F2 11 04 CF D3 C4 A9 3E D1 A2 B4 50 DD 2B 6C 9C 4E BC 62 0A 97 08 AC 10 CA 77 3C FB 38 95 B8 DF 8F BD 7D 71 E7 98 21 CD 58 02 62 FF B7 B1 47 9D 79 81 A3 14 9B EA 76 A6 2B E4 A2 6F F9 DA F3 7C 77 85 B9 AE 72 5E 3E DC 1B 55 FC 76 03 78 71 0F 48 C4 23 21 D1 AB C2 C0 44 19 54 42 D6 63 25 5F 19 8A 8E C0 5D DE 02 1D A9 25 34 75 AC D0 FD AD 85 5F B8 44 48 5C 5F F7 5E 03 6D D9 CD 35 10 54 01 06 64 2A B0 07 8D E7 7D B5 A3 BC 1A A2 37 8D C6 FA F6 36 7D 5B 46 3D AB 25 7A 43 0F 4E C9 6F 74 02 C9 DD 54 B8 1F 0A 5C 65 3A D5 2C 0A 84 F7 CA 9D 8A 4D 6F 21 13 C8 9D 8E 99 32 8C DD 8C 77 91 07 5E C5 58 A6 01 76 75 FB 91 4D 58 F7 18 0D A3 B7 2D ED 9C F5 38 8C 2C EE B0 96 04 D0 01 7B 96 4E 6D 06 4B 47 D1 E1 04 8D E5 37 21 65 4E 22 E6 BB 1C B7 10 65 0A 9E 5A 5A EA 41 C3 18 27 7C 19 F6 0F 24 E1 4C CD B2 2A B4 E2 C9 45 39 28 DC 30 B3 95 7A EA C3 ED 93 C4 0A F8 2F F5 CB 9F D5 7B E8 05 97 78 87 70 CF 0F 18 44 4C CA C8 42 BF 67 35 9D 73 A9 B1 55 4B 11 8E A7 84 E1 98 C7 10 0B C7 C7 E0 83 DB 65 38 43 9B 74 68 95 55 54 0F C2 B4 63 1A E8 A5 4A A0 D8 F9 80 19 8F 37 DC 84 37 08 93 E7 E8 67 50 BC 87 B2 52 24 31 0F 53 73 F8 4B EB 5C AB 35 08 71 BC 83 45 96 8E BA E9 45 1B 8C 7B 74 C5 6D EE DE 4E D8 CE 59 01 A6 41 FB A9 92 A5 9D 18 32 FA 84 C7 32 0A 60 5D 1B 24 03 B9 68 84 E0 47 0D 2B E0 83 9D 1B 9E 71 F8 AB EE 0D C8 B8 60 A5 7B F5 5D 75 62 CF 0E 2F 43 23 2D A3 75 15 3B D9 85 E4 97 2F CF E2 49 30 98 5F 10 28 91 81 6C 8D F5 36 E6 53 13 BA 85 4A 0E 50 54 91 F2 60 77 E0 4D 33 1D AB 46 BE DA 57 6E 3C 0D 50 C4 A2 A9 76 91 0E 7B 33 6A 46 BF 8F 79 65 53 D6 80 89 7E 43 5E D7 71 27 8A FA 91 D3 2A E9 CC 81 7A B5 84 CB BF A5 A4 5E D5 26 69 E1 24 F2 05 F0 83 FC C7 35 70 35 D9 3A BE 77 7A 8E 76 B0 1E B9 98 72 75 2F B0 01 DE 9E 54 2C 25 2D 9D B6 BF 07 04 FE 63 10 7F 93 6E 48 0B AD B7 DA 1A 00 FC 1C 70 56 C2 14 39 2C 61 CD F2 A7 0A C9 8D F3 FD 15 FE 18 38 BD B8 AA B9 09 EA 8F 51 11 B1 55 69 F3 1C 5F 89 D5 69 BA 4F 81 7B 55 20 CE 1F 87 E0 8D 0D 01 DA E0 C0 3D 89 F6 2B FE E6 49 E9 99 57 DD 32 AA 47 03 8D FD 14 63 C6 A7 99 B8 06 38 DE 82 DC A1 4D 72 4E 4E 0F 3F 34 50 74 76 CE FA 7B 40 02 4C 7C 12 59 7E 24 62 48 08 18 55 4D FF 40 4B 54
Public Key Size: 1334 bytes
Signature (Raw Bytes): 27 CB 90 27 A3 68 7A 85 E3 88 8E 22 32 A9 46 5E 6F 0E B4 1B 3D 5B 36 98 C4 FA F2 02 52 79 B2 4C 7F 27 94 5B 0E FF 2D CD 23 CF 5D 14 4B 27 61 0A DA 7A 19 38 3E B2 4E 81 7D 42 18 1F BB CB 51 97 7A 08 BF A2 7D C1 78 92 45 3A FA 0E B2 AF 22 3C 9E D2 8D 72 6F 2F 6A 28 BB 2F 54 03 DA 2C 56 CE E2 A2 49 98 A4 9B F5 B7 EA 61 03 82 D9 01 3F 34 78 1E 46 E2 D9 A1 E0 3F C2 8D FF BC 9B 74 3B 62 47 79 8B 37 A6 74 A0 F8 18 79 09 98 52 D2 1F 78 85 50 7E CE 9F D7 28 31 BC 5C 5E CC FE ED C9 56 65 D3 66 DB 9F 63 5D FD 8B 3E F5 19 70 42 6E 6B 91 EF D0 44 DC 33 95 F1 7D C7 B0 E0 AD 75 C1 F7 4D D7 A2 DC 4D 0B 4F 7C 6D 1B D1 89 A6 E5 31 E4 ED AA 43 C6 7D 7F F6 E0 47 9F FE 76 27 18 C5 AE DA 5C 21 6E FA AC 0A 2B 3A 67 AF A8 58 CF 8C 0E E6 59 21 51 0A 62 FA C5 87 AE 8D 86 D9 7D C1 B4 C1 2D D7 13 4C A4 BB E0 36 03 02 20 2D 18 7D F3 B3 A3 15 3D 26 E7 14 64 4B B4 4F 7A 47 EE 2F 32 26 1C E6 BB 0F 13 38 50 12 93 52 F0 9E 76 3F 6D E1 FD 35 7F 20 FF D9 E5 F3 C8 BF 84 AC 96 7A F8 9C 3B 1B B9 77 D1 87 DE D1 EE E2 86 64 3C 17 E4 8E C0 C8 E2 EF 10 ED A0 E5 09 EC 02 9F C0 34 0F 20 BA F4 BC 13 62 CD 11 6E 93 FE 01 D9 CC 90 59 C9 F5 0E AD D6 ED B7 97 EE 3C A7 17 F8 07 40 C2 A6 E0 C3 D8 1F C5 34 4D C5 C9 66 8E 6E 28 62 D2 13 51 2E F7 70 CA 26 BD A1 C9 A6 A1 3B 7D E8 E2 9D BB 7B 63 F4 07 99 C5 EE 07 B7 10 1B 44 30 B1 75 24 B5 F1 98 7D 1F 5E 15 9C 46 84 23 EC A3 3B D4 54 DF 69 FC CD 72 50 DE 6E D0 55 E5 49 BF 7F F3 B9 13 E2 F2 3A 22 6F EC 84 56 03 86 CF 13 91 E9 0A 31 46 03 1E EE 25 0A 1F 44 93 BC BA FA 44 09 7F A3 01 6B 54 EC EC C4 32 79 0D EE AA 1D 2A 20 0F CF 27 08 9C CC 39 90 08 77 19 C2 76 74 69 AA 00 CD C5 99 18 D7 4D B0 6E FD 99 17 DD 16 93 50 D7 2C 4B 78 10 DF 87 59 A2 05 04 81 8C CF AE 7A 45 84 87 84 0A 62 F2 A9 95 59 68 AD AF 18 33 32 60 D3 3B B4 31 FF 72 BA C4 9F DB 82 E0 33 6D E3 40 10 5D 99 EF 52 AA 50 A9 F3 9F 0F A5 36 7D 3A 8A 6A F5 DD 42 DC 1D B6 D0 1C 93 9E 41 96 99 7F DE 3B 4F 00 AF EB 0D CA BA 15 BF 0D E1 D8 20 A7 DD 89 C6 AD 1F 72 72 7F 43 00 D3 1A AD CF 3E 0F E6 03 67 E0 9F BF E9 17 E2 2B 00 EF EF 24 48 E2 03 FE A1 18 0C 4F 6B A6 E6 F8 76 FA B5 11 4C B4 05 37 4B 1A 39 58 2C 64 5B 00 5A FC F4 60 F0 29 44 3E 19 AD 5F 80 36 E3 FD F7 84 39 5B B4 0F 9B 04 DC B6 01 EE E2 82 E7 F3 D5 B6 5C FD A0 01 AC ED 76 4F 07 8F 6C F0 CC CD 12 68 10 8D C8 AC FB 49 71 66 8E 8A 16 A0 6A 71 05 7E F1 5E 7C 76 A3 D2 49 D2 21 6A FB 04 AA F1 70 43 78 40 35 B0 7A 06 48 D4 9A 46 52 A8 FE 3A 4F B7 1C 5E F0 09 8F E8 BD D0 7D 74 71 70 D1 24 85 44 C2 FD A3 43 D2 12 4E D1 1F 97 88 BE 8D AC 7A 1A 9F C4 48 C3 33 D4 F4 F2 C5 FF 93 02 83 AE 83 51 3D CA 7E 5D 85 1B 18 ED B4 92 49 BA A6 55 23 BF E3 CE E9 AB C5 97 69 F5 F6 45 11 C8 60 5F 8F DB 4B 54 9F 92 B3 14 8A 53 08 80 8D 91 F8 E4 DF 6A 78 FA C5 95 F4 79 6A D0 78 6F 1F AE 22 21 26 1D 02 B3 59 A5 A4 01 A0 01 D6 24 2D 37 78 31 7E 25 59 01 01 D6 99 A0 73 FA CB CD 7B FD C4 A6 6F AD 79 0E AF DC 95 F0 9A 35 15 3F 12 A1 F1 F2 C8 87 44 F6 6E D7 84 21 27 A1 BE C7 A2 0F AB 34 30 87 D1 77 3A E7 F8 F7 57 B5 3C 02 73 FF 67 E4 D1 C4 0D E7 91 22 57 3E F6 BA 93 7C E3 C3 E7 B4 E7 A9 79 F8 93 76 BC CA A3 1E D8 CB E2 EE E1 BB F8 2A AB B8 2A 55 09 05 14 B7 9E 6E 75 78 36 70 D2 03 4A 1D 68 C6 67 6D 48 B0 3B D6 04 59 CA 37 FE 55 17 A9 41 59 69 97 1C 9A 67 C4 DD 64 25 B9 A6 B3 83 F6 2B C5 75 F7 59 9C 17 09 C3 F8 96 E2 A5 67 5A FF 0B 5C 33 C9 07 5C A9 41 FA 8A 8D 6A 4F BC DE 8E B1 20 17 39 CE DD 5E 1D 13 67 C8 67 2A 5C 31 43 6F BD 25 77 DD DD A6 35 A8 BC 14 AB AC 52 86 EB 1C 5F 77 3E C9 F2 99 48 41 30 86 36 80 CC 0C F6 0F 84 03 4A 45 98 1E 8D 48 97 E4 FE 44 BC DD A2 E0 87 C3 D8 8F EE D0 F6 0D A0 AB 83 A3 94 C6 C5 DA ED 2B B8 02 32 76 BA 5A AA 43 E2 BD 5E 7B 67 87 04 36 83 7E 93 49 65 F3 1F E4 B8 9D EA 51 52 F3 00 41 3C 99 01 DF E8 D4 58 17 80 A6 BD FE C4 57 FD 9E B1 93 59 0A 71 39 EF 4F 03 B8 60 80 DE 3A 21 11 D7 7B 7B CE 89 FE 73 5A FF 24 36 5A 18 2E 31 4C D5 8B 0F 85 2C 42 95 57 2A 74 72 69 68 D6 EB F6 6D 2F 40 86 FB 1A 24 EF C5 29 09 0A 92 BA B0 3D DB DC 1F A4 5D 14 D1 75 28 79 0A 10 39 FA 97 BD 5E 5C D8 C1 70 9F 49 24 22 74 9D E8 A5 D5 45 5A 36 05 84 9E F8 0F 6E 62 EC 1D AE F6 04 8A CD 0F 90 C8 0F 77 4E 46 F7 CB 8A A7 DE 45 4E 9C D3 6A 39 EC 48 14 14 06 95 AD 18 E1 E3 03 33 35 0B 01 4E D3 00 55 49 F0 D4 70 14 B1 71 27 12 E7 E9 57 ED BB 1D 4F B1 D3 1B D8 FB 62 47 B6 8A 2F EC A9 B0 2F 3A A4 26 F6 BB 52 F6 88 8B 00 A7 F9 33 DA 1B F5 D6 3E CD 36 1D AA E9 A8 DC 1D EF 76 2E 6B EB E5 00 DD C8 F1 24 15 DE F6 52 28 A3 C0 83 EF D2 17 82 43 D3 9E AA DA 21 B0 89 66 C5 D6 ED 1F 08 29 AC BD A7 25 F7 59 78 35 5D 0A 38 C1 AA 1A AB 07 25 84 75 9F 9F C9 01 64 05 24 08 9A EC 88 68 8C 1F 23 C3 D1 B6 C5 DA F7 AD AF 0B 0F B3 40 6B EA 65 F0 D7 17 DD EA AA E7 6A BD 7F F8 58 69 97 2A FF 77 A3 D0 B2 2D 03 87 24 59 27 3A 81 A8 41 47 BD A4 AD 2B B6 79 5D B0 A1 2F C3 6B BC 89 58 54 30 B6 4B F8 4E EF DA FF CB 34 69 FD 13 6F 08 DD B5 74 19 25 FB E9 4D 87 66 73 9E 82 10 F4 24 64 FC EB 90 E1 20 D1 50 28 75 10 2C 33 D2 6C 5F 2B FB 60 6B 83 49 07 23 8A A5 AE 82 49 12 5A 8B A1 40 A8 71 11 AB 3F EA D6 13 63 B9 57 1E 23 09 C0 2F CF 25 22 E4 96 AB 7A 91 C2 32 4E BD 91 AB 2C 92 C9 69 FC D8 D0 74 18 11 D0 47 98 DB 83 68 C5 9D AD 1E 28 36 45 95 16 99 8B 1F 9E 05 AC DC 63 41 67 A8 EF 48 25 D7 C6 F0 F7 7B F9 42 3B 91 A6 51 B9 29 D4 E7 C4 8D BE 71 ED 47 44 13 DF 8C 6A F8 EE B1 21 3C A0 49 21 9C E6 4A AA D9 BA EA 9F CF 7C 74 F3 AA AD 88 0F ED 65 7A 0C 1A 5B 66 27 5C EF AC 19 BB 04 CC 52 C4 0D C4 84 99 5E 94 D2 DB AB 12 39 87 6A AD CE E7 D8 80 CC D2 9B C8 0D FF CB 35 E8 70 53 EC D7 EF 8D 42 75 25 37 FA D9 66 DD FB D2 25 FD 62 2E 74 99 4F 08 FB D8 FB 44 A1 11 5C D6 5D 21 F2 0A FB EE 44 DA 82 7B 15 51 A6 17 A2 6A DC 9D 30 90 E4 98 40 C8 F9 91 1C B0 09 BE 40 81 FF 77 2A AE 5C 88 50 F4 15 CE 2F 38 FA 11 39 C5 CC 2A 9C F2 99 01 96 3B 14 61 97 9D 72 0C BA 90 5F 51 64 48 B1 D7 09 5D AA EF 55 52 60 C3 24 B7 7F 30 A8 7F 6F A9 8D 17 9D 24 84 2A 5D 64 72 FB 49 38 1F CC 00 5F 06 0A 23 05 45 20 56 81 8B B4 F4 0D F9 49 56 29 C8 AE 6A CE 3C 31 4E 55 09 A6 71 05 0E 7B C0 F5 42 CA 0B 33 BC 3A D0 14 C9 40 DA 54 EA BB 54 A5 EE E6 BF 67 A7 C6 51 4F 96 89 A1 E6 F6 99 58 39 8A 9E A4 34 91 FA 6C A4 06 F9 03 02 74 00 11 E8 B0 E2 9B 58 76 E9 6F 43 E8 0D DD 19 6B 92 9F 9E 28 95 4B 93 CB 87 B1 08 90 B4 62 83 F0 BE DD 13 66 3F CB 7F 7B 5C 66 7A 40 BE F3 6D B4 68 E6 93 AD EE 2C 34 AB 58 C5 8F 83 45 4A 69 D9 43 49 C5 D3 8E 1C 6F 37 84 37 16 88 79 B5 B2 20 BB FF 5F 23 C1 CA F8 DA 5D CA 1A 9A 79 5C B7 91 BC 49 73 E0 6E BF C5 AD 6C 8C 73 0B 97 69 D4 77 86 9B 69 00 F2 AE 2B 5E 28 B0 05 B9 FB 14 AA 0B B3 32 40 0D B0 15 C2 D9 A8 D3 7D 12 60 DB D0 EA F4 BF 21 AC 7A EE 91 B8 D2 47 4A 55 66 4F 17 0A 0C 04 09 5C C9 73 6A D2 EC 7C BB B5 A8 37 1D 66 19 1D F8 DF 09 69 C2 43 1A 60 BB 44 73 6A EB 1F 29 C9 35 A9 62 D4 E2 50 BA 60 05 9D 3C DA 75 57 B4 D2 52 96 CC 30 63 1D 9C 13 B7 3E D8 DB 06 AA 33 88 A8 E6 53 6A 52 89 7C 3F 60 BE 73 DA BB D3 FF B9 56 2C F4 B9 3E 84 89 24 E8 73 B0 37 F5 C5 C3 D9 79 66 DF CB D0 8D 8D DE 07 28 36 D9 A6 81 34 68 6D 8B 8B 83 91 C2 8E BB 18 06 B4 3D C0 6B 94 94 01 41 80 E8 F7 38 4C 0D 59 5E 6A 0A 09 58 B2 13 0B 38 AA 9D 4F AD 30 23 F6 85 50 0A 3C 9E DF 78 4F 95 8B 67 04 11 24 3B 77 78 A8 CC D2 E5 F2 F3 54 5A 5E 76 79 7B 92 BB DD FF 01 0B 13 2D 2E 42 45 54 5D 5E 78 B4 B7 C5 D5 D7 03 3B 3E 44 49 51 5D B7 BB EA EC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 16 26 31
Signature Size: 2420 bytes
Signature Valid: true

ASN1 DER를 파싱하면 스펙의 사이즈와 일치하는 것을 확인할 수있다.

 

'PKI' 카테고리의 다른 글

AES 운영 모드 비교  (0) 2025.03.28
ECIES-X963-SHA256-AESGCM  (0) 2025.03.17
[EC] 디지털 서명 3종  (0) 2025.03.16
[양자내성암호] Kyber 찍먹해보기  (0) 2025.02.20
전자서명(pkcs#7)과 전자봉투  (0) 2019.12.22

ECIES-X963-SHA256-AESGCM을 살펴보자.

ECIES  ECDH(키 교환) 후 대칭키 암복호화를 수행하는 것을 의미
X963-SHA256  공유키 유도 방식
AES-GCM  AES 대칭키 암호화. GCM은 MAC 역할
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.hashes import SHA256
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.kdf.x963kdf import X963KDF
import os

# AES-GCM 암호화 함수
def aes_gcm_encrypt(key, plaintext):
    iv = os.urandom(12)  # GCM IV (12바이트)
    cipher = Cipher(algorithms.AES(key), modes.GCM(iv))
    encryptor = cipher.encryptor()
    ciphertext = encryptor.update(plaintext) + encryptor.finalize()
    return iv, ciphertext, encryptor.tag  # (IV, 암호문, 인증 태그)

# AES-GCM 복호화 함수
def aes_gcm_decrypt(key, iv, ciphertext, tag):
    cipher = Cipher(algorithms.AES(key), modes.GCM(iv, tag))
    decryptor = cipher.decryptor()
    return decryptor.update(ciphertext) + decryptor.finalize()

# ECDH 키 교환 및 KDF (X9.63-KDF with SHA-256)
def derive_shared_key(private_key, peer_public_key):
    shared_secret = private_key.exchange(ec.ECDH(), peer_public_key)
    print(f"shared key : {shared_secret.hex()}")
    kdf = X963KDF(algorithm=SHA256(), length=32, sharedinfo=None)  # 256-bit AES key
    return kdf.derive(shared_secret)

# 🔹 1️⃣ Alice와 Bob의 키 쌍 생성 (SECP256R1 사용)
alice_private_key = ec.generate_private_key(ec.SECP256R1())
bob_private_key = ec.generate_private_key(ec.SECP256R1())

alice_public_key = alice_private_key.public_key()
bob_public_key = bob_private_key.public_key()

# 🔹 2️⃣ Alice가 Bob의 공개 키를 받아 대칭 키 생성
alice_shared_key = derive_shared_key(alice_private_key, bob_public_key)

# 🔹 3️⃣ Bob이 Alice의 공개 키를 받아 같은 대칭 키 생성
bob_shared_key = derive_shared_key(bob_private_key, alice_public_key)

assert alice_shared_key == bob_shared_key  # 키가 동일해야 함

# 🔹 4️⃣ Alice가 메시지를 암호화하여 Bob에게 전송
plaintext = b"Hello"
iv, ciphertext, tag = aes_gcm_encrypt(alice_shared_key, plaintext)

# 🔹 5️⃣ Bob이 받은 데이터를 복호화
decrypted_message = aes_gcm_decrypt(bob_shared_key, iv, ciphertext, tag)

print(f"📩 암호화된 메시지: {ciphertext.hex()}")
print(f"🔓 복호화된 메시지: {decrypted_message.decode()}")

1. alice & bob은 secp256r1 곡선으로 키 쌍 생성

2. alice/bob 개인키와 bob/alice 공개키로 ECDH 수행하여 공유키 유도

3. 공유키를 키 유도(X.963-SHA256)하여 공유 AES 대칭키 유도

4. 공유 AES 대칭 키로 AES-GCM 수행

'PKI' 카테고리의 다른 글

AES 운영 모드 비교  (0) 2025.03.28
[PQC] 격자 기반 전자 서명 테스트(java24)  (0) 2025.03.19
[EC] 디지털 서명 3종  (0) 2025.03.16
[양자내성암호] Kyber 찍먹해보기  (0) 2025.02.20
전자서명(pkcs#7)과 전자봉투  (0) 2019.12.22
곡선 알고리즘 사용 사례 특징
secp256r1 ECDSA 범용 (NIST 추천) 속도 느림
secp256k1 ECDSA 블록체인 속도 느림
Ed25519 EdDSA SSH 속도 빠름 / 공개키 : 256바이트 (고정 크기)

# secp256k1 예시

from ecdsa import SECP256k1, SigningKey, VerifyingKey
from ecdsa.util import sigencode_der, sigdecode_der
import hashlib

# Alice (서명자)
def alice_sign(message):
    # Alice의 개인키 생성
    sk = SigningKey.generate(curve=SECP256k1)
    # Alice의 공개키 생성
    vk = sk.get_verifying_key()
    
    # 메시지 해싱
    message_hash = hashlib.sha256(message.encode('utf-8')).digest()
    print(f"Alice가 해싱한 메시지: {message_hash.hex()}")
    
    # 서명 생성
    signature = sk.sign(message_hash, sigencode=sigencode_der)
    print(f"Alice의 서명: {signature.hex()}")
    
    return signature, vk

# Bob (검증자)
def bob_verify(message, signature, vk):
    # 메시지 해싱
    message_hash = hashlib.sha256(message.encode('utf-8')).digest()
    print(f"Bob이 해싱한 메시지: {message_hash.hex()}")
    
    # 서명 검증
    try:
        vk.verify(signature, message_hash, sigdecode=sigdecode_der)
        print("서명 검증 성공!")
        return True
    except:
        print("서명 검증 실패!")
        return False

# Alice가 서명
message = "Alice의 중요한 메시지"
print(f"서명할 메시지: {message}")
signature, alice_vk = alice_sign(message)

# Bob이 서명 검증
bob_verify(message, signature, alice_vk)
서명할 메시지: Alice의 중요한 메시지
Alice가 해싱한 메시지: 2491722cc10f5bd7bc9f79ae476ba2c1055dab43be2fca9dc81e0718a1381642
Alice의 서명: 3044022029160eb2534be33a8311639465202dcdee5a7725fc41cd9f01e1c8d986a66688022003c159499de24335b0c89d4a34cc35b0714b58d935ed615cc131b1ab2278d7ad
Bob이 해싱한 메시지: 2491722cc10f5bd7bc9f79ae476ba2c1055dab43be2fca9dc81e0718a1381642
서명 검증 성공!

서명 구조 (der)

SEQUENCE 태그, 서명 구조의 시작 30
서명 길이 44
 r의 INTEGER 태그 02
r의 길이 20 (0x20)
r 값  29 16 0E B2 53 4B E3 3A 83 11 63 94 65 20 2D CD EE 5A 77 25 FC 41 CD 9F 01 E1 C8 D9 86 A6 66 88
s의 INTEGER 태그 02
s의 길이 20 (0x20)
s 값 03 C1 59 49 9D E2 43 35 B0 C8 9D 4A 34 CC 35 B0 71 4B 58 D9 35 ED 61 5C C1 31 B1 AB 22 78 D7 AD

# secp256r1 예시

from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization
import hashlib

# Alice (서명자)
def alice_sign(message):
    # Alice의 개인키 생성 (secp256r1 사용)
    sk = ec.generate_private_key(ec.SECP256R1())
    
    # Alice의 공개키 생성
    vk = sk.public_key()
    
    # 메시지 해싱
    message_hash = hashlib.sha256(message.encode('utf-8')).digest()
    print(f"Alice가 해싱한 메시지: {message_hash.hex()}")
    
    # 서명 생성
    signature = sk.sign(message_hash, ec.ECDSA(hashes.SHA256()))
    print(f"Alice의 서명: {signature.hex()}")
    
    return signature, vk

# Bob (검증자)
def bob_verify(message, signature, vk):
    # 메시지 해싱
    message_hash = hashlib.sha256(message.encode('utf-8')).digest()
    print(f"Bob이 해싱한 메시지: {message_hash.hex()}")
    
    # 서명 검증
    try:
        vk.verify(signature, message_hash, ec.ECDSA(hashes.SHA256()))
        print("서명 검증 성공!")
        return True
    except:
        print("서명 검증 실패!")
        return False

# Alice가 서명
message = "Alice의 중요한 메시지"
print(f"서명할 메시지: {message}")
signature, alice_vk = alice_sign(message)

# Bob이 서명 검증
bob_verify(message, signature, alice_vk)
서명할 메시지: Alice의 중요한 메시지
Alice가 해싱한 메시지: 2491722cc10f5bd7bc9f79ae476ba2c1055dab43be2fca9dc81e0718a1381642
Alice의 서명: 304402202797f1bd7f59f0f2a7865655fd2999ca1d1e5158b29d546cb71aa57155ab901502201165c74887c2ad384c9f8cf6a7b4de771c4bd06467bf396422bcee39527b60d4
Bob이 해싱한 메시지: 2491722cc10f5bd7bc9f79ae476ba2c1055dab43be2fca9dc81e0718a1381642
서명 검증 성공!

서명 구조가 secp256k1과 동일

# ed25519 예시

from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives import hashes
import hashlib

# Alice (서명자)
def alice_sign(message):
    # Alice의 개인키 생성 (ed25519 사용)
    sk = ed25519.Ed25519PrivateKey.generate()
    
    # Alice의 공개키 생성
    vk = sk.public_key()
    
    # 메시지 해싱
    message_hash = hashlib.sha256(message.encode('utf-8')).digest()
    print(f"Alice가 해싱한 메시지: {message_hash.hex()}")
    
    # 서명 생성
    signature = sk.sign(message_hash)
    print(f"Alice의 서명: {signature.hex()}")
    
    return signature, vk

# Bob (검증자)
def bob_verify(message, signature, vk):
    # 메시지 해싱
    message_hash = hashlib.sha256(message.encode('utf-8')).digest()
    print(f"Bob이 해싱한 메시지: {message_hash.hex()}")
    
    # 서명 검증
    try:
        vk.verify(signature, message_hash)
        print("서명 검증 성공!")
        return True
    except:
        print("서명 검증 실패!")
        return False

# Alice가 서명
message = "Alice의 중요한 메시지"
print(f"서명할 메시지: {message}")
signature, alice_vk = alice_sign(message)

# Bob이 서명 검증
bob_verify(message, signature, alice_vk)
서명할 메시지: Alice의 중요한 메시지
Alice가 해싱한 메시지: 2491722cc10f5bd7bc9f79ae476ba2c1055dab43be2fca9dc81e0718a1381642
Alice의 서명: 1a9e8142f0ca566e3bdb67330816c7592c2882d3c3ccd154d5c29c7795aabdc82271aa22370d64adcc1eedb868f9448d25fdbf407b145dda90ba08d8cf29fa00
Bob이 해싱한 메시지: 2491722cc10f5bd7bc9f79ae476ba2c1055dab43be2fca9dc81e0718a1381642
서명 검증 성공!

서명 구조

r (32바이트) 1a9e8142f0ca566e3bdb67330816c7592c2882d3c3ccd154d5c29c7795aabdc8
s (32바이트) 2271aa22370d64adcc1eedb868f9448d25fdbf407b145dda90ba08d8cf29fa00

Kyber는 키 캡슐화 메커니즘으로, 쉽게 설명하면 공유 키(AES)를 유도할때 사용한다고 보면 된다.

Kyber의 보안 강도는 아래와 같다.

Kyber-512 = AES-128

Kyber-768 = AES-192

Kyber-1024 = AES-256

매개변수 세트 공개키 사이즈 개인키 사이즈 암호문 사이즈 공유키 사이즈
Kyber512 800 바이트 1632 바이트 768 바이트 32 바이트
Kyber768 1184 바이트 2400 바이트 1088 바이트 32 바이트
Kyber1024 1568 바이트 3168 바이트 1568 바이트 32 바이트

 

테스트 코드 : https://github.com/pq-crystals/kyber 빌드 후, test_vectors를 실행

*공식에서는 Kyber768 사용을 권장하지만, 귀찮아서 그냥 Kyber512로 진행하였음

1. Bob이 공개 키와 비밀 키를 생성

Public Key: c29ac66c84bee3f129508c2b8c790c99a5ca41e5707e9b8c75c04d7ea8a481980a358b066a4a7e28d15d10374f75c33da6029cd490746fb55f5feab2ce823dec1830c0c18ef89ba3cc3bce4d252a07a40d401a4c8d273618b595db21ca4a959eb4d133556801b2b78254b2b5955c0400962dbb5a487aaa24a430b614e2af9338afd4b0339bd830a9cb761db1a83220352dd523b8a583022ca13e246506548c57ba3850ac5c50d864e2d48b89694277cc7a8174ad7b1ba2ee621d57d29b23c22df831872051145d2535dbb025e29c6da38cb475958e2a8808a431bed5b486821a1513a729cd979b6c8b382503cf53337616e1059ddc59977219d2f17b32acabbe86c468c1267b2b862ac565a7e232266c83fc700cda19b616377389428e62614cd6ac9f08fb12d21827feb324b14bc16cc0c20904b3973b9dfe60af577776449ac34eb00989e5a876143bc9b930a3c2a5bb861208f225dd97625bb36b2d8810d0452e458968b90c6a6d97c2dfca7341d53c741a60e2b91385c86bb3b1be5f10708c546ae6318209ba268dd2b4e3e4722761491ae215600248e7541e6080b865f44a169c02a5b374f1fa5502333753979c9da75452c4814a8b8fd682b8e0370699296bc2f42d38e5a2de92c5f5f61f24b65e1b9b75249b8759708706640000b490937683e1ccbbf39a0baecb1edd62826721524bcc4d3bf06f8e5ab368aa426eb42c701839e8bbcc69dbccd2757f84c60a409b6629d98dc92947367c52f0698c3c41c01110bafbeb0621cc175170375f8250c0f62406e32e10725b47e3c165845a7ada8fb2c55555f5cc8602246fe06f875a6eb5c9459dd19292428492a76738b8057e84c8e11436c4eb788e494e3952657ed331a2e4a47d75492365c473f484200502868c733bb9b2b3e44af2c98adfb91a4e1a144eec5a32d24f13c78775f206d7a94dee12007f778e484a1430666bfeda6dbb31b757d72b5c79a469522fe6599abb45b52cc6403c4970f65684bb770ca78893ba439057013655309cd84c524c9ca558e3612041b7b2026e2187598afb46f1d4ca85096dbc9bcc1c25779dfb607052e11649bb7f5f7268f979c4d8140afe6ce53830f38602290d751427f07b27
Secret Key: 7cf108c75a4d3592053d0ca79ce527ec1734f7023656e26253e2bfc68960dea73d28d7a9821597b48b4504837e27132c8ebc48505303aeb568f9d1928f7244cf98b4a88843c5db69845abfc4e40683dca3bde694445c63cc512bd2e4608e91a5697738bbca3b09a98da49757ad65c085125d11d01178d15acb251f417cbeff2a2ac1b05dc70839ffb297be205152e98371745de76243d3a302dfda7f16f5a8f0d2b73021a7f5c0490ff6b5a4125843889364288bede430835cce5bf8b86377132aea3ced911311a43b87e10ae471b49f1a31b636ce5d7c415d7c17539575724c3166ab23ca183f9962a0b17190f3dc204dc2551eec234b7c4e298a4e60f15d4e40bcaf1ba0eaa806e214bda0a0b0e0f51b34745e148290e222a4496c946766029cd82964429fd85a30ee3c0c6dea4e6bc840237c38d8e9b6a893702444bfeef783a104a8b46b8309a914cbaaa8cec9c08bb54a3cfc1a22c5a9d1b87685a30417d846d5e22242e8c0c8316cb7f15832b70b4bbc453bb67485e34c87d9a2d4b294d257a98d864afab445aea6bf4830404d170ca7484cc799b73ae3ce375c3a13d1318bd29158620328c8bc22d812d269c8ec133ce4f977bd95300054b5ef246bb086a6d3340575464183e10db1a126f81a43d2f800e962568de3411515b90dc1256446cf8fc33149e66a8657c221335eb57a8ca6262b06981a032823222c9da22835271033212b4e9d516132a428709b5882ab8764771832968dc73c4cd241adb145b5e654b38bab03e3524f113525dd0a63e8f195fceb26b8b03063c4863459cc10c5884cac016eebb7afa2519b27293b845e7e893e70bb21d0e004f1d05015dc71fcf6b150c750aa98c96f89c8da199eefc1712c409bc833a84d404ad72c873bf910c9190645b94dd2a31347596029d22abd071f5387588a9917fee4b33d1bbcfa1858390662b656c09ff824ed177abf44a118b7c78bba96b9f9b5a3a54e597829be686868e5463f99be58da0be7886501730e01e26aad0535896616d98125c38b3eb778114176b1bd498ebd92b5bd0a98a0a39f77b599c3e63e66fb62167b06c29ac66c84bee3f129508c2b8c790c99a5ca41e5707e9b8c75c04d7ea8a481980a358b066a4a7e28d15d10374f75c33da6029cd490746fb55f5feab2ce823dec1830c0c18ef89ba3cc3bce4d252a07a40d401a4c8d273618b595db21ca4a959eb4d133556801b2b78254b2b5955c0400962dbb5a487aaa24a430b614e2af9338afd4b0339bd830a9cb761db1a83220352dd523b8a583022ca13e246506548c57ba3850ac5c50d864e2d48b89694277cc7a8174ad7b1ba2ee621d57d29b23c22df831872051145d2535dbb025e29c6da38cb475958e2a8808a431bed5b486821a1513a729cd979b6c8b382503cf53337616e1059ddc59977219d2f17b32acabbe86c468c1267b2b862ac565a7e232266c83fc700cda19b616377389428e62614cd6ac9f08fb12d21827feb324b14bc16cc0c20904b3973b9dfe60af577776449ac34eb00989e5a876143bc9b930a3c2a5bb861208f225dd97625bb36b2d8810d0452e458968b90c6a6d97c2dfca7341d53c741a60e2b91385c86bb3b1be5f10708c546ae6318209ba268dd2b4e3e4722761491ae215600248e7541e6080b865f44a169c02a5b374f1fa5502333753979c9da75452c4814a8b8fd682b8e0370699296bc2f42d38e5a2de92c5f5f61f24b65e1b9b75249b8759708706640000b490937683e1ccbbf39a0baecb1edd62826721524bcc4d3bf06f8e5ab368aa426eb42c701839e8bbcc69dbccd2757f84c60a409b6629d98dc92947367c52f0698c3c41c01110bafbeb0621cc175170375f8250c0f62406e32e10725b47e3c165845a7ada8fb2c55555f5cc8602246fe06f875a6eb5c9459dd19292428492a76738b8057e84c8e11436c4eb788e494e3952657ed331a2e4a47d75492365c473f484200502868c733bb9b2b3e44af2c98adfb91a4e1a144eec5a32d24f13c78775f206d7a94dee12007f778e484a1430666bfeda6dbb31b757d72b5c79a469522fe6599abb45b52cc6403c4970f65684bb770ca78893ba439057013655309cd84c524c9ca558e3612041b7b2026e2187598afb46f1d4ca85096dbc9bcc1c25779dfb607052e11649bb7f5f7268f979c4d8140afe6ce53830f38602290d751427f07b27cda93dec4c4dc4d8484457fd882399c4b918c49fa8389a1dfa8c9f92f39b00cf3cb1eea988004b93103cfb0aeefd2a686e01fa4a58e8a3639ca8a1e3f9ae57e2

2. Alice는 Bob의 공개 키를 사용하여 공유 키를 유도하고, 이를 캡슐화 함

Ciphertext: 5a645120b878936d202efc4851f38e6bb6573c3b14b0b9bb44bf372d8b1aa8034a9f1a1584076f0a38e89a9d49a50b792ace7584981be8e239272deef914418fefe2dad97dc0ec20cfe8a9599b9bbe3ecce91f97e10cd9ef2c4950e3ea3c46fe481eb0d24878c4624ad344f0dc9863e7d170937a8cecc6f7d00f9565529d572959cc49d0f7042ff43b7d1d71efd22f2654e14e78c31f34a26ae53b067ae0380a65a732459503da5e9406d50a70e3d5ebdbf3c9c01cad1cc001ebe69e6cff20e64ce5c802b691587e404cf6efa2799a2ffd353492a75f0e2ea52a974e0545a086a3bd14b69045238140a7200b10c3276cc6b2a67c173f7c1ad64545adb8ebdf7835e9aa1f54f6891369988f3625c45f2fec8d9a07b911d32ba69d9ff5d74f10a6808b25a3c81709945bf213c3450d74481f065042186b0d36fb55271162dfaf41e516a408f83ccabe8a0ba7effa16f88f6d7dbdb64e608c8f18d686c7e5d548d737116fa562dc76e7994a86374a9c85b8b17c4f025fa23a4de1a997a87e5a65f5c5386772491fd8d10731f5f5aa60366ffe3fd209cb7b7a8615320ad0728f41e812bd88d2d6104753917e89e1ca0f10177cf5dab040e466908b27446215709b0912972c428c4d9aad9432d9a159069c96154001cb0be4de597e9871b04bddaa4539f838bc12ab0a3ea7e8c8481bcdfcc1834369fcf061f7c599efdc4f6c434102991446aea12881e163fd4ee6c458b82e42759f8b11b0612c12d5a777acf4c7cdd26fb7da0b9098dc4af94704daa529945ab169cdb22d3966fcd26950e2418cac9bc7dc32c4a604f368f0f8a9c7ddce8b5e476b26b33116d607df1b49c205ada0d2ea5a5a64eecb22549ddf18a0daed2e5d44cb6174b9781236eee11f95ab0c45836bcafc73af3bec11440bc1c605669eb019cfac0097943cf29bbffce0f823293da623e5fa6d2a7ee0c7b4507596a62ef46bbe4e1b63cc96ba9878a7b39f84b59dd336f1659a24cbb33015d515e9e80e3e7902b1d583f8ee97153cd8ba1fadeb9ee7e2f2c23dfee85a50d5c3554b79922a4537d6dc4f09418dfdd744596cbf68
Shared Key: 221d7d86011659313c83ce3fd0ab26797ef217e11d1f0bc76e7952fbe52a0a58

3. Bob은 Alice가 보낸 캡슐화된 키를 자신의 비밀 키로 복호화하여 Alice와 동일한 공유키를 얻음

Shared Key: 221d7d86011659313c83ce3fd0ab26797ef217e11d1f0bc76e7952fbe52a0a58

 

Kyber 공식 홈페이지에서는 하이브리드를 권장한다. 예) Kyber+ECDH
키 교환에 대해서는 아래를 참조
https://www.ietf.org/archive/id/draft-ietf-tls-hybrid-design-12.html

 

만약 크롬을 사용중이라면, 아래에 접속하여 TLS 1.3 kyber 사용을 활성화 할 수 있다.

 

 

 

Windows 10 기준으로,

C:\Program Files\NPKI\yessign\USER 디렉토리를 보면 공인인증서가 있습니다.

signCert.crt / signPri.key

signPri.key에서 개인키를 추출하고 RSA구조체로 변환할 것입니다.


1. SEED 대칭키 / IV 구하기

1) 개인키 파일에서 salt와 iteration 값을 추출합니다. PKCS#8 규격에 맞춰서 추출합니다.

# 8바이트 salt 추출하기 (20번째 바이트에서 8바이트 추출)

BYTE bySalt[8] = { 0, };

memcpy_s(bySalt, 8, (BYTE*)byFileBuffer + 20, 8);

# iteration 값 추출하기 (30번째 바이트에서 2바이트 추출)

WORD wIteration = _byteswap_ushort(*((WORD*)byFileBuffer + 15));

빅 엔디언을 리틀 엔디언으로 변경해줍니다.


2) KEY와 IV만들기

공인인증서 개인키는 SEED-CBC-128로 암호화되어 있습니다.

복호화할 KEY와 IV를 PBKDF1규격에 따라 만듭니다.

공인인증서 패스워드에 salt를 붙인다음 iteration 값 만큼 SHA1하며, 최종 값에서 첫 16바이트를 KEY로 사용합니다.


최종 HASH값에서 뒤 4바이트를 잘라낸 뒤 SHA1하여 DIV를 만듭니다. DIV에서 앞 16바이트를 잘라서 IV로 사용합니다.


2. SEED로 개인키 복호화

1에서 구한 키와 IV로 SEED-CBC-128 복호화하면 ASN.1 DER형태의 바이너리가 나옵니다.

복호화 할 오프셋은 파일의 36번째부터 끝까지입니다.


3. RSA 구조체로 변경하기

ASN.1을 PKCS8 구조체로 변환 후 RSA구조체로 변환합니다.

4. 개인키로 평문 암호화 


'PKI' 카테고리의 다른 글

[EC] 디지털 서명 3종  (0) 2025.03.16
[양자내성암호] Kyber 찍먹해보기  (0) 2025.02.20
전자서명(pkcs#7)과 전자봉투  (0) 2019.12.22
openssl rsa 키 생성 테스트  (1) 2016.01.01
[OpenSSL] Convert RSA Structure to PEM  (0) 2014.12.16

개인키 생성

openssl genrsa -out privatekey.pem 1024

개인키 정보 출력

openssl rsa -in privatekey.pem -text -out private.txt

modulus : 00을 제외하고 128개, 128*8 = 1024bit

prime1, prime2 : 00을 제외하고 64개, 64*8 = 512bit

modulus(N) = prime1(P) * prime2(Q)

공개키 : publicExponent(65537), N

개인키 : privateExponent(D), N

exponent1 : D mod (P-1)

exponent2 : D mod (Q-1)

coefficient : (inverse of Q) mod P

공개키 생성

openssl pkey -in privatekey.pem -pubout -out publickey.pem

공개키 정보 출력

openssl pkey -in privatekey.pem -text_pub


64비트 키 검증

http://www.mathpapa.com/algebra-calculator.html 로 계산 가능

Private-Key: (64 bit)

modulus: 00:c6:cf:f1:d2:1c:ba:3d:bb

publicExponent: 65537 (0x10001)

privateExponent: 0f:04:29:c9:88:d9:02:61

prime1: 3825875939 (0xe40a3be3)

prime2: 3744484937 (0xdf304e49)

exponent1: 553066949 (0x20f721c5)

exponent2: 2212512545 (0x83e04321)

coefficient: 2971090683 (0xb1173efb) 


p * q = modulus = 14325934824416231424 (C6CFF1D21CBA3DBB)



RSA 구조체를 PEM으로 변환하는 방법입니다.

파일 혹은 버퍼로 저장할 수 있습니다.

+ Recent posts