환경 : Ubuntu 24.04.3 / 램 16G

SaaS를 사용 못하는 내부망에서 사용하기 위함

2025.08.12 기준

1. 도커 설치 (https://docs.docker.com/engine/install/ubuntu/ 참조)

$ wget https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/containerd.io_1.7.27-1_amd64.deb && \
wget https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/docker-ce-cli_28.3.3-1~ubuntu.24.04~noble_amd64.deb && \
wget https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/docker-ce_28.3.3-1~ubuntu.24.04~noble_amd64.deb && \
wget https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/docker-buildx-plugin_0.26.1-1~ubuntu.24.04~noble_amd64.deb && \
wget https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/docker-compose-plugin_2.39.1-1~ubuntu.24.04~noble_amd64.deb
$ sudo dpkg -i ./containerd.io_1.7.27-1_amd64.deb ./docker-ce-cli_28.3.3-1~ubuntu.24.04~noble_amd64.deb ./docker-ce_28.3.3-1~ubuntu.24.04~noble_amd64.deb ./docker-buildx-plugin_0.26.1-1~ubuntu.24.04~noble_amd64.deb ./docker-compose-plugin_2.39.1-1~ubuntu.24.04~noble_amd64.deb
$ sudo service docker start & sudo docker run hello-world

2. 리버스 프록시 설치

$ sudo apt-get install nginx
# 인증서 만들기
$ IP=192.168.130.189
$ sudo openssl req -x509 -newkey rsa:2048 -days 825 -nodes -subj "/CN=${IP}" -addext "subjectAltName = IP:${IP}" -keyout /etc/ssl/private/sentry-ip.key -out /etc/ssl/certs/sentry-ip.crt
$ sudo vim /etc/nginx/sites-available/sentry.conf
# 80 -> 443 리다이렉트
server {
  listen 80;
  return 301 https://$host$request_uri;
}

# HTTPS 종단 (IP 기반, 기본 서버)
server {
  listen 443 ssl http2;

  ssl_certificate     /etc/ssl/certs/sentry-ip.crt;
  ssl_certificate_key /etc/ssl/private/sentry-ip.key;

  client_max_body_size 50m;

  location / {
    proxy_set_header Host               $host;
    proxy_set_header X-Forwarded-Host   $host;
    proxy_set_header X-Forwarded-Proto  https;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:9000;
  }
}
$ sudo ln -s /etc/nginx/sites-available/sentry.conf /etc/nginx/sites-enabled/sentry.conf
$ sudo nginx -t
$ sudo systemctl reload nginx

3. Self-Hosted Sentry 설치 (https://develop.sentry.dev/self-hosted/ 참조)

$ sudo apt-get install git curl
$ VERSION=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/getsentry/self-hosted/releases/latest)
$ VERSION=${VERSION##*/}
$ git clone https://github.com/getsentry/self-hosted.git
4 cd self-hosted
$ git checkout ${VERSION}
$ sudo ./install.sh

$ vim sentry/config.yml
system.url-prefix: "https://192.168.130.189"
$ vim sentry/sentry.conf.py
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
USE_X_FORWARDED_HOST = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SOCIAL_AUTH_REDIRECT_IS_HTTPS = True
CSRF_TRUSTED_ORIGINS = ["https://192.168.130.189"]
$ sudo sed -i -E 's|proxy_set_header[[:space:]]+X-Forwarded-Proto[[:space:]]+\$scheme;|proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;|g' nginx.conf

$ sudo docker compose up --wait

4. curl  + sentry 에러 전송 예제

라이브러리 설치

$ sudo apt install -y libcurl4-openssl-dev
$ git clone --recursive https://github.com/getsentry/sentry-native.git
$ cd sentry-native
$ cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo   # 백엔드는 기본값 사용
$ cmake --build build --parallel
$ sudo cmake --install build

CMakeLists.txt 생성

cmake_minimum_required(VERSION 3.20)
project(app CXX)

find_package(sentry CONFIG REQUIRED)
add_executable(app main.cpp)
target_link_libraries(app PRIVATE sentry::sentry)
#include <sentry.h>
#include <cstdio>
#include <stdexcept>

int main() {
    const char* DSN = "https://님_공개키@192.168.130.189/2";

    sentry_options_t* options = sentry_options_new();
    sentry_options_set_debug(options, 1);
    sentry_options_set_logger(options,
        [](sentry_level_e lvl, const char* msg, void*) {
            std::fprintf(stderr, "[sentry:%d] %s\n", (int)lvl, msg);
        }, nullptr);

  
    sentry_options_set_dsn(options, DSN);
    sentry_options_set_database_path(options, ".sentry-native");
    sentry_options_set_ca_certs(options, "아까만든인증서.crt");
    sentry_options_set_release(options, "myproject@1.0.0");    
    sentry_options_set_handler_path(options, "/usr/local/bin/crashpad_handler");

    // 원한다면 환경/태그
    sentry_options_set_environment(options, "dev");
    
    if (sentry_init(options) != 0) {
        throw std::runtime_error("sentry_init failed");
    }

    // 테스트 이벤트
    std::array<void*, 256> frames{};
    int n = backtrace(frames.data(), frames.size());

    sentry_value_t st  = sentry_value_new_stacktrace(frames.data(), n);
    sentry_value_t exc = sentry_value_new_exception("error", std::string(msg).c_str());
    sentry_value_set_by_key(exc, "stacktrace", st);

    sentry_value_t evt = sentry_value_new_event();
    sentry_event_add_exception(evt, exc);
    sentry_capture_event(evt);

    // 크래시
    int* p = nullptr; *p = 42;

    sentry_close();
}

4. sentry-cli 설치 및 환경 설정

https://192.168.130.189/settings/account/api/auth-tokens/new-token/ 에서 토큰 생성

$ curl -sL https://sentry.io/get-cli/ | bash
# 환경 파일 설정
$ vim ~/.sentryclirc
[defaults]
url = https://192.168.130.189
org = sentry # 조직 slug
project = agent # 프로젝트 slug

[http]
verify_ssl = false

[auth]
token = 님_토큰

# 정상 동작 확인
$ sentry-cli info
# 조직 slug 확인
$ sentry-cli organizations list
+----+--------+--------+--------------+---------------+--------------+
| ID | Name   | Slug   | Date Created | Early Adopter | Requires 2FA |
+----+--------+--------+--------------+---------------+--------------+
| 1  | Sentry | sentry | 2025-08-12   | false         | false        |
+----+--------+--------+--------------+---------------+--------------+
# 프로젝트 slug 확인
$ sentry-cli projects list -o sentry
+----+----------+--------+----------+
| ID | Slug     | Team   | Name     |
+----+----------+--------+----------+
| 1  | internal | Sentry | Internal |
| 2  | agent    | Sentry | agent    |
+----+----------+--------+----------+

# 파일 유효성 확인
$ sentry-cli debug-files check 님_실행파일
# 분리 심볼 생성
objcopy --only-keep-debug 님_실행파일 님_실행파일.debug
objcopy --add-gnu-debuglink=님_실행파일.debug 님_실행파일
# 파일 업로드
$ sentry-cli debug-files upload --include-sources 님_실행파일 님_실행파일.debug

5. 크래시패드 정상 전송을 위해 프로그램을 설치한 pc에 인증서 설치

# sentry 서버에서 인증서 가져와서 루트 인증서에 설정
$ sudo cp sentry-ip.crt /usr/local/share/ca-certificates/sentry-ip.crt
$ sudo update-ca-certificates
#include <iostream>
#include <Poco/Logger.h>
#include <Poco/PatternFormatter.h>
#include <Poco/FormattingChannel.h>
#include <Poco/ConsoleChannel.h>
#include <Poco/FileChannel.h>
#include <Poco/SplitterChannel.h>
#include <Poco/AutoPtr.h>
#include <Poco/Thread.h>
#include <Poco/Runnable.h>

using namespace Poco;

class LevelFilterFileChannel : public FileChannel
{
public:
    LevelFilterFileChannel() : FileChannel() {}

    void log(const Message& msg) override
    {
        // debug, trace 로그 제외
        if (msg.getPriority() <= Message::PRIO_INFORMATION)
        {
            FileChannel::log(msg);
        }
    }
};

class MyWorker : public Runnable
{
public:
    void run() override
    {
        Logger& logger = Logger::get("aLogger");
        for (int i = 0; i < 5; ++i)
        {
            logger.notice("Poco Thread is running! i = " + std::to_string(i));
            Poco::Thread::sleep(500); // 0.5초 대기
        }
        logger.information("Poco Thread done.");
    }
};

int main()
{
    AutoPtr<ColorConsoleChannel> colorConsoleChannel(new ColorConsoleChannel);
    AutoPtr<LevelFilterFileChannel> fileChannel(new LevelFilterFileChannel);
    fileChannel->setProperty("path", "myapp.log");
    fileChannel->setProperty("rotation", "50000 K"); // 50,000KB 초과시 회전
    fileChannel->setProperty("archive", "timestamp");
    fileChannel->setProperty("purgeAge", "30 days"); // 30일 초과 로그 파일 삭제

    AutoPtr<PatternFormatter> patternFormatter(new PatternFormatter);
    patternFormatter->setProperty(
        "pattern",
        "[%Y-%m-%d %H:%M:%S] [%p] [PID:%P][TID:%T][TH:%I] %t"
    );
    patternFormatter->setProperty("times", "local");
   
    AutoPtr<FormattingChannel> fcConsole(new FormattingChannel(patternFormatter, colorConsoleChannel));  // 콘솔은 모든 로그
    AutoPtr<FormattingChannel> fcFile(new FormattingChannel(patternFormatter, fileChannel));

    // 콘솔 및 파일 채널로 메시지를 전달
    AutoPtr<SplitterChannel> splitter(new SplitterChannel);
    splitter->addChannel(fcConsole);
    splitter->addChannel(fcFile);  

    Logger& logger = Logger::get("Logger");
    logger.setChannel(splitter);
    logger.setLevel(Message::PRIO_TRACE); // 모든 로그 레벨 허용

    logger.fatal("FATAL 메시지");
    logger.critical("CRITICAL 메시지");
    logger.error("ERROR 메시지");
    logger.warning("WARNING 메시지");
    logger.notice("NOTICE 메시지");
    logger.information("INFO 메시지");
    logger.debug("DEBUG 메시지 - 콘솔만");
    logger.trace("TRACE 메시지 - 콘솔만");

    MyWorker worker;
    Thread thread;
    thread.start(worker);

    // 메인 스레드도 로그 남기기
    for (int i = 0; i < 3; ++i)
    {
        logger.notice("Main thread working... i = " + std::to_string(i));
        std::this_thread::sleep_for(std::chrono::milliseconds(400));
    }

    thread.join();
    logger.information("모든 작업 종료");
}

환경 : ubuntu 24.04.02 LTS

 

# copy & paste 활성화
sudo apt install open-vm-tools open-vm-tools-desktop -y

#재부팅!

# clion 설치
sudo snap install clion --classic

# libbpf 관련 설치
cd ~
sudo passwd root
su
apt install clang clang-tools git libelf-dev make gcc llvm pkg-config libcap-dev libbfd-dev cmake
git clone --recurse-submodules https://github.com/libbpf/libbpf
git clone --recurse-submodules https://github.com/libbpf/bpftool
cd libbpf/src
make install
cd ~/bpftool/src
make install

 

  • 함수가 배열 또는 컨테이너(예: std::vector)의 뷰(view) 만을 필요로 할 때.
  • 함수가 읽기 전용 또는 수정 가능한 시퀀스를 받아야 할 때.
  • 함수가 컨테이너의 타입에 독립적이어야 할 때 (std::vector, std::array, C-style 배열 모두 수용).

 

✅ 예제 시나리오: 버퍼를 받아 총합 계산

✅ std::span 사용 버전 (깔끔, 안전, 범용)

#include <iostream>
#include <vector>
#include <array>
#include <span>

int sum(std::span<const int> data) {
    int total = 0;
    for (int value : data) {
        total += value;
    }
    return total;
}

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::array<int, 5> arr = {1, 2, 3, 4, 5};
    int c_array[] = {1, 2, 3, 4, 5};

    std::cout << sum(vec) << "\n";      // OK
    std::cout << sum(arr) << "\n";      // OK
    std::cout << sum(c_array) << "\n";  // OK

    return 0;
}

❌ std::span 없이 타입별 오버로드 버전 (지저분하고 유지보수 어려움)

#include <iostream>
#include <vector>
#include <array>

int sum_vector(const std::vector<int>& data) {
    int total = 0;
    for (int value : data) {
        total += value;
    }
    return total;
}

int sum_array(const std::array<int, 5>& data) {
    int total = 0;
    for (int value : data) {
        total += value;
    }
    return total;
}

int sum_c_array(const int* data, size_t size) {
    int total = 0;
    for (size_t i = 0; i < size; ++i) {
        total += data[i];
    }
    return total;
}

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::array<int, 5> arr = {1, 2, 3, 4, 5};
    int c_array[] = {1, 2, 3, 4, 5};

    std::cout << sum_vector(vec) << "\n";             // OK
    std::cout << sum_array(arr) << "\n";              // OK
    std::cout << sum_c_array(c_array, 5) << "\n";     // OK

    return 0;
}

다수의 제어기가 신뢰할 수 있는 CA를 기반으로 암호화 된 메시지를 주고 받을 수 있도록 설계

1. CA 키 세러머니 (secp256r1)
2. 제어기 1, 2는 EC 키 쌍 생성 (secp256r1)
3. TEE 스토리지에 개인키 저장
4. 제어기 1, 2는 CSR 생성 (OID, 기기명 포함) 후 CA에 전송
5. CA에서 CSR 서명하여 각 제어기에 인증서 발급
6. 제어기 1,2에 CA 및 제어기 인증서를 하드 디스크에 저장
7. 제어기 1,2는 CA에 CRL 목록 요청 후 하드 디스크에 저장

제어기 1 Side
8. 제어기 2로 전송할 평문 생성
9. EC 임시키 생성 (secp256r1) : 1회 사용 후 폐기 (ECDHE 연산에만 사용하고, 그 결과로 세션키(HKDF)를 도출하는 용도)
10. TEE내 안전 저장소에서 개인키 로드 (2번에서 생성)
11. HKDF 인자(랜덤 salt, info(제어기1➜제어기2)) 생성 : 1회용 세션 설정을 위함.
12. HKDF 인자, 제어기1 인증서, 제어기1 임시공개키를 개인키(2번에서 생성)로 서명(SHA256withECDSA)
13. 제어기 1, 2간 세션(소켓) 생성
14. HKDF 인자, 제어기 1 인증서, 임시 공개키, 12번 값을 제어기2에 전송

제어기 2 Side
15. CA 공개키로 제어기 1의 인증서 검증 (검증 실패하면 에러 처리)
16. CRL 확인하여 폐기 여부 검사 (검사 실패하면 에러 처리)
17. 인증서 용도 확인(oid 및 인증 용도)
18. 제어기1 인증서(공개키)로 데이터 서명값 검증 (SHA256withECDSA) (검증 실패하면 에러 처리)
19. EC 임시키 생성 (secp256r1)
20. TEE내 안전 저장소에서 개인키 로드 (2번에서 생성)
21. 제어기2 인증서, 제어기2 임시공개키를 개인키(2번에서 생성) 로 서명 (SHA256withECDSA)
22. 제어기1의 임시 공개키와 제어기2의 임시 개인키로 ECDHE 공유키 유도 
23. 수신한 salt, info 및 공유키를 사용하여 HKDF(HMAC-based Key Derivation Function) 세션키 유도
24. 제어기 2 인증서, 임시 공개키, 21번 값을 제어기1에 전송

제어기 1 Side
25. CA 공개키로 제어기 2의 인증서 검증 (검증 실패하면 에러 처리)
26. CRL 확인하여 폐기 여부 검사 (검사 실패하면 에러 처리)
27. 제어기2 인증서(공개키)로 데이터 서명값 검증 (SHA256withECDSA) (검증 실패하면 에러 처리)
28. 제어기2 의 임시 공개키와 제어기1의 임시 개인키로 ECDHE 공유키 유도 
29. salt, info 및 공유키를 사용하여 HKDF 세션키 유도
30. 제어기2에 전송할 랜덤 IV, AAD(제어기1 기기명, timestamp, 시퀀스(리플레이 공격 대비)) 생성
31. HKDF 세션키로 평문을 AES-GCM 암호화
32. iv, aad, tag, 암호문을 개인키로 서명 (SHA256withECDSA)
33. iv, aad, tag, 암호문, 32번 을 제어기2에 전송

제어기 2 Side
34 제어기1 인증서(공개키)로 데이터 서명값 검증 (SHA256withECDSA) (검증 실패하면 에러 처리)
35. aad 내 timestamp 검증 (10초 이내면 통과)
36. aad내 시퀀스 검증 (최근 수신된 aad의 시퀀스를 확인후, 그 다음으로 예상되는 시퀀스값이 아니면 replay 공격으로 간주)
37. AAD내 기기명과 제어기1 인증서 확장필드의 기기명이 일치하는지 확인
38. HKDF 세션키로 AES-GCM 복호화 (iv, aad, tag 사용)
39. 제어기1, 2 간 세션(소켓) 해제

목표 : 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 통합  (0) 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 통합  (0) 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 등에서 사용

새롭게 출시된 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를 파싱하면 스펙의 사이즈와 일치하는 것을 확인할 수있다.

 

'Applied Cryptography' 카테고리의 다른 글

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

+ Recent posts