목표 : github CI에 AI SAST 도구인 CodeRabbit을 통합하여 취약점을 관리하도록 함. SonarCloud와는 다르게 Pull Request만 리뷰 가능함. (2주 무료)

CodeRabbit 설정

1. https://www.coderabbit.ai/

2. Get a free trial

3. Login with GitHub

4. Add Repositories

5. repo Settting에서 Review Language 변경

GitHub 설정

6. repo 루트에 .coderabbit.yaml 생성

language: "ko-KR"
early_access: false
reviews:
  profile: "chill"
  request_changes_workflow: false
  high_level_summary: true
  poem: true
  review_status: true
  collapse_walkthrough: false
  auto_review:
    enabled: true
    drafts: false
chat:
  auto_reply: true

7. 코드 수정 후 Pull Request

8. 리뷰 참조 : https://github.com/codetronik/aabbcc/pull/3

'devSecOps' 카테고리의 다른 글

[GitHub] SonarCloud 통합  (0) 2025.04.07
[GitHub] 기본 CI 구축  (0) 2025.04.07

목표 : github CI에 SAST 도구인 SonarCloud을 통합하여 취약점을 관리하도록 함

SonarCloud 설정

1. https://sonarcloud.io/

2. GitHub / Birbucket / GitLab 등을 선택할 수 있다. GitHub 선택

3. Import an organization 선택 

4. 적용을 원하는 repo 선택 후 Install & Authorize

5. 키와 Organization 키 설정 후, 요금 플랜 선택 후 Create Organization 선택

6. 분석을 원하는 repo 선택 후 Set Up 선택

7. 새 코드 범위 설정 후 Create project 선택

Previous Version : 커밋 후 변경된 모든 코드를 새코드로 간주

Number of days : 지난 x일 동안 변경된 모든 코드는 새코드로 간주

8. Information에서 Project Key와 Organization Key 확인

이 키는 GitHub가 SonarCloud에 접근할 때 사용 됨

9. Administration -> Analysis Method -> Automatic Analysis 해제

9. My Account -> Security -> 토큰 이름 지정 후 Generate Token 선택

이 토큰은 GitHub가 SonarCloud에 접근할 때 사용 됨

GitHub 설정 (예제가 궁금하다면 https://github.com/codetronik/KeyStoreExample 참조)

1. Settings -> Secrets and variables -> Actions -> New repository secret  선택

Name엔 SONAR_TOKEN, Secret엔 9번에서 생성한 토큰 입력

2. build.gradle.kts 수정

plugins {
	alias(libs.plugins.android.application) apply false
	alias(libs.plugins.kotlin.android) apply false
	id("org.sonarqube") version "4.4.1.3373" // 추가!!
}

3. yml 수정

name: Android Build with SonarCloud

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    name: Build Debug APK & Analyze with SonarCloud
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Set up JDK 17
      uses: actions/setup-java@v4
      with:
        distribution: 'temurin'
        java-version: '17'
        cache: gradle

    - name: Set up Android SDK
      uses: android-actions/setup-android@v3

    - name: Grant execute permission for Gradle
      run: chmod +x ./gradlew

    - name: Run SonarCloud analysis
      env:
        SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
      run: |
        ./gradlew sonar \
          -Dsonar.projectKey=8번에서 확인한 키 \
          -Dsonar.organization=8번에서 확인한 키 \
          -Dsonar.host.url=https://sonarcloud.io \
          -Dsonar.login=${SONAR_TOKEN}
          
    - name: Build Debug APK
      run: ./gradlew assembleDebug

    - name: Upload Debug APK
      uses: actions/upload-artifact@v4
      with:
        name: debug-apk
        path: app/build/outputs/apk/debug/app-debug.apk

4. 빌드 완료 후, 분석 결과를 SonarCloud  에서 확인 가능

시큐리티 failed 발생

내용을 확인하면, 자격 증명(pin / 패턴 등) 없이 키스토어에 접근이 가능하다고 함.

'devSecOps' 카테고리의 다른 글

[GitHub] CodeRabbit 통합  (2) 2025.04.07
[GitHub] 기본 CI 구축  (0) 2025.04.07

목표 : 기존 github repo에 CI 구축

1. repo에서 Actions 선택

2. CI설정이 안되어 있다면, Suggested for this repository가 보일 것이다. Simple workflow -> Configure 선택

3. 기존 내용은 지우고, 아래와 같이 입력

name: Android Build (Debug APK)

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    name: Build Debug APK
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Set up JDK 17
      uses: actions/setup-java@v4
      with:
        distribution: 'temurin'
        java-version: '17'
        cache: gradle

    - name: Set up Android SDK
      uses: android-actions/setup-android@v3

    - name: Grant execute permission for Gradle
      run: chmod +x ./gradlew

    - name: Build Debug APK
      run: ./gradlew assembleDebug

    - name: Upload Debug APK
      uses: actions/upload-artifact@v4
      with:
        name: debug-apk
        path: app/build/outputs/apk/debug/app-debug.apk

4. 빌드가 진행되는 것을 확인할 수 있다.

'devSecOps' 카테고리의 다른 글

[GitHub] CodeRabbit 통합  (2) 2025.04.07
[GitHub] SonarCloud 통합  (0) 2025.04.07
모드 설명 특징
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

https://github.com/codetronik/optee-aes

1. 키 설정

TA에서는 OP-TEE API를 활용하여 eMMC의 RPMB(Replay Protected Memory Block) 파티션에 키를 생성하고 삭제할 수 있다. 이 영역은 Normal World에서 접근할 수 없다.

별칭(alias)을 지정하여 키에 접근한다. (TA간 키는 공유할 수 없다. 즉, alias가 동일하더라도, 다른 TA의 alias에 접근할 수 없다.) RPMB에 키가 존재하지 않으면, 키를 생성하여 저장한다. 

TA 관련 주요 API들은 중요 데이터 저장을 위해 세션을 제공한다. 뭘 저장할 지는 자유이며, 필자는 이 곳에 키를 저장하였다.

2. AES-GCM을 구현

세션에서 키를 불러온 후, 이를 사용하여 데이터를 암/복호화한다. TA에서는 암호화 과정에서 IV를 랜덤하게 생성하며, 최종적으로 생성된 태그(tag)와 암호문(cipher)을 함께 반환한다.

'Embedded' 카테고리의 다른 글

[OP-TEE with QEMU] 2. 예제 코드 컴파일 및 실행  (0) 2025.02.26
[OP-TEE with QEMU] 1. 환경 구축  (0) 2025.02.25
라즈베리파이5 환경 구축  (0) 2025.02.23

소스 : https://github.com/codetronik/optee_example

프로젝트 구조는 아래와 같이 구성되어야 한다. (어떻게 만들던 상관없지만, Normal 과 TA는 분리되어 있어야 개발이 편해진다.)

├── include
│   └── common.h
├── normal
│   └── main.cpp
└── ta
    ├── Makefile
    ├── ta.c 
    ├── sub.mk // 필수 파일
    └── user_ta_header_defines.h // 필수 파일

유저가 OP-TEE OS의 Normal World(일반 리눅스 영역)에서 main을 실행하면, Secure World의 TA와 통신하게 된다.

TA 소스는 콜백 함수 구현이므로, 반드시 C로 작성하여야 컴파일이 된다. Normal은 C++로 작성해도 상관 없다. 

TA와 Normal 각각 컴파일 하여야 한다.

필자는 라즈베리파이를 사용 중이라 크로스컴파일러 설치를 안했으므로, 참고 바람.

normal의 경우 필자는 clang을 사용했다.

// normal
clang --sysroot=/home/code/optee/out-br/host/aarch64-buildroot-linux-gnu/sysroot -o main main.cpp -lteec -std=c++20 -lstdc++ -Wunused-parameter
// TA
make

TA 실행 파일(11223344-5566-7788-99aa-bbccddeeff00.ta)은 /lib/optee_armtz에 복사한다. Normal은 /tmp 등 적절한 곳에 복사한다. 우분투<->QEMU간 파일 전송은 #1편을 참조

Secure World 콘솔을 보면, Hello 가 로깅된 것을 확인할 수 있다.

참조 : https://optee.readthedocs.io/en/latest/building/trusted_applications.html

'Embedded' 카테고리의 다른 글

[OP-TEE with QEMU] 3. 키 생성 및 AES  (0) 2025.03.13
[OP-TEE with QEMU] 1. 환경 구축  (0) 2025.02.25
라즈베리파이5 환경 구축  (0) 2025.02.23

목표 : qemu에 op-tee os를 설치한 후 테스트

필자 환경 : ubuntu 24.04.2 (라즈베리파이)

sudo apt update
sudo apt upgrade
sudo apt install -y adb acpica-tools autoconf automake bc bison build-essential ccache cpio cscope curl device-tree-compiler e2tools expect fastboot flex ftp-upload gdisk git libattr1-dev libcap-ng-dev libfdt-dev libftdi-dev libglib2.0-dev libgmp3-dev libhidapi-dev libmpc-dev libncurses5-dev libpixman-1-dev libslirp-dev libssl-dev libtool libusb-1.0-0-dev make repo mtools ninja-build python3-cryptography python3-pip python3-pyelftools python3-serial python-is-python3 rsync swig unzip uuid-dev wget xdg-utils xsltproc xterm xz-utils zlib1g-dev

mkdir -p ~/optee && cd ~/optee

git config --global user.email "1.com"
git config --global user.name "1"

repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml -b 4.5.0
repo sync -j16 --no-clone-bundle

cd build
make -j16 toolchains

make -j16 #크로스 컴파일
make run #op-tee os 구동

make run-only # 2번째 실행부터는 이 명령어로 접속

화면이 뜨면 c 입력

 

Normal World에서 root 입력

 

예제 테스트

공유 폴더 설정하는 방법

[호스트]

vi /home/code/optee/build/Makefile

QEMU_RUN_ARGS 문자열 검색 후 아래 추가 (path는 본인 경로에 맞게)

QEMU_RUN_ARGS += -fsdev local,id=fsdev0,path=/home/code,security_model=mapped,multidevs=remap -device virtio-9p-pci,fsdev=fsdev0,mount_tag=hostshare

 

[OP-TEE OS]

mkdir -p /mnt/host
mount -t 9p -o trans=virtio hostshare /mnt/host

+ Recent posts