콘텐츠로 이동

English · 한국어

첫 PQC 이관, 단계별 안내

양자내성암호(PQC) 이관을 막 맡았거나 그 진행을 따라가야 하는 사람을 위한 안내입니다. 작은 예 하나를 이관의 다섯 단계에 따라 따라가며, 단계마다 pqcota가 무엇을 주고 사람이 무엇을 결정해야 하는지 밝힙니다. 작업의 순서를 소개하는 글이고 프로젝트 계획서가 아닙니다. pqcota의 개요는 README, 운영 질문은 FAQ, 결과를 보고서로 만드는 일은 보고 안내를 보세요. 연결된 문서 중 한국어판이 없는 것은 영문입니다.

왜 패치가 아니라 프로젝트인가

NIST는 오늘의 공개 키 암호를 깰 수 있는 양자컴퓨터가 언제 나올지 아무도 정확히 모르며 추정은 몇 년에서 수십 년까지 다양하다고 밝힙니다. 또 시스템을 새 표준으로 옮기는 데 10년에서 20년이 걸릴 수 있고, 공격자가 지금 암호화된 데이터를 기록해 두었다가 나중에 풀 수 있다고 하며, 조직이 전환을 시작하도록 권합니다(NIST). 2024년 8월 13일 NIST는 첫 양자내성 표준을 발표했습니다. FIPS 203(키 설정용 ML-KEM)과 FIPS 204(ML-DSA), FIPS 205(SLH-DSA)이며 뒤의 둘은 전자서명용입니다(NIST 발표). 전환기에는 많은 시스템이 고전 알고리즘과 양자내성 알고리즘을 결합한 하이브리드 키 교환을 쓰며, 둘 중 하나라도 안전성을 유지하는 한 공유 비밀이 보호되도록 하는 것을 목표로 합니다(IETF RFC 9954).

그것만으로는 무엇을 먼저 해야 하는지 알 수 없습니다. 답은 시스템이 실제로 무엇을 쓰는지에 달려 있기 때문입니다. 기한과 어떤 데이터나 시스템을 먼저 다룰지는 규제 기관, 업종, 사용자 자신의 위험 판단에 달려 있습니다. 이 안내는 그것을 정하지 않습니다. 사용자가 따르는 기관(규제 기관, 조직의 책임 부서)에서 받으세요.

어디서나 같은 것은 작업의 순서입니다.

  1. 무엇을 다룰지, 그리고 어떻게 관측할지 정한다.
  2. 실제로 무엇이 쓰이는지, 그리고 무엇을 보지 못했는지 알아낸다.
  3. 무엇을 어떤 순서로 바꿀지 정한다.
  4. 변경을 승인하고, 실행하고, 되돌릴 방법을 남긴다.
  5. 다시 관측하고, 그것이 무엇을 증명하고 무엇을 증명하지 않는지 적는다.

pqcota는 첫째와 둘째 단계, 그리고 마지막 두 단계를 돕습니다. 셋째 단계는 일부러 사용자에게 맡깁니다.

예

pqcota 자체 데모와 같은 작은 결제 서비스입니다.

  • web-gw: OpenSSL 3.0.13이 도는 웹 게이트웨이. 다음 두 시스템에 연결합니다.
  • pay-app: OpenSSL 3.5.5가 있는 시스템의 Java 애플리케이션. 실행 중에 애플리케이션이 등록하는 보안 provider(BC)도 씁니다.
  • pay-db: OpenSSL 1.1.1f가 도는 데이터베이스 서버.

아래에 인용한 출력은 2026-09-30에 데모를 실행한 것이며 줄여 놓았습니다. 데모는 실험실 환경이므로 실제 환경에서 할 일과 다른 곳은 이 안내가 그렇다고 밝힙니다.


1단계. 무엇을 다룰지, 어떻게 관측할지 정한다

결정(사람): - 어떤 시스템을 다루고, 왜 그것들을 먼저 하는가. 기술이 아니라 사업과 위험의 결정입니다. - 발견한 자산 중 관리하지 않을 잡음은 무엇인가. 예를 들어 배포판의 기본 라이브러리입니다. - 얼마나 자주 다시 볼 것인가. 관측 한 번은 그 순간만 보여 줍니다.

pqcota가 주는 것: - 시스템을 등록하는 방법. 그 밖의 시스템에서 온 결과는 말없이 받아들여지지 않고 거부되며 그 수가 집계됩니다. - 관리하고 싶지 않은 것을 빼는 자산 규칙, 그리고 뺀 수. 제외는 없음이 아닙니다. - 관측을 하나하나 기록하는 이력. 그래서 「마지막으로 본 때」와 「마지막으로 바뀐 때」를 모두 알 수 있습니다.

예에서: 실제 환경이라면 web-gw, pay-app, pay-db를 등록하고, 다른 패키지에 속한 런타임을 빼는 자산 규칙을 더할 것입니다. 데모는 앞의 것을 하지 않습니다. 등록 목록을 받지 않고, 적재 출력에 scope gate: skipped (no CMDB given)라고 나옵니다. 자산 규칙은 적용하여 Python 런타임과 SSH 데몬을 빼며, 적재 요약이 이 규칙으로 발견 항목이 몇 개 제외됐는지 보고하므로, 보고서가 그 항목들을 처음부터 없었던 것처럼 읽히게 하지 않습니다.

범위를 지금 숫자로 적어 두세요. 다루려던 시스템이 몇 개인지입니다. 나중에 보지 못한 것이 얼마인지 말하려면 그 숫자가 필요합니다. 단위는 보고 안내가 설명합니다.

2단계. 실제로 쓰이는 것과 보지 못한 것을 알아낸다

pqcota가 주는 것: 시스템별로 찾은 암호 라이브러리와 Java 보안 provider, 연결별로 지켜보는 동안 양쪽이 합의한 알고리즘, 그리고 각각의 등급입니다.

pay-app
  • JCA provider chain: SUN,SunRsaSign,…,BC   [confirmed]
      (this BC is in no configuration file; the application registered it while running)
  • OpenSSL libcrypto 3.5.5                    [confirmed]
pay-db
  • OpenSSL libcrypto 1.1.1f                   [confirmed]

🟢 web-gw → pay-app   TLS  X25519MLKEM768
🟢 web-gw → pay-app   SSH  sntrup761x25519-sha512@openssh.com
🔴 web-gw → pay-db    TLS  x25519
🔴 web-gw → pay-db    SSH  curve25519-sha256
grade totals: 🟢 2 · 🔴 2 · ⚪ 0

이렇게 읽으세요. - X25519MLKEM768은 하이브리드 그룹의 이름으로, X25519 ECDH와 ML-KEM-768을 결합한 것입니다(IETF RFC 10024, 7.1절). 🟢은 양자내성 또는 하이브리드 알고리즘이 협상됐다는 뜻이고 🔴은 고전 알고리즘이 협상됐다는 뜻입니다. 🔴은 「취약하다」는 판정이 아니며, 무엇이 협상됐는지에 대한 사실일 뿐입니다. - 🔴 연결은 pay-db로 가며, 데모는 둘을 다르게 설명합니다. TLS 연결이 고전인 것은 OpenSSL 1.1.1에 양자내성 그룹이 없기 때문입니다. SSH 연결이 고전인 것은 그곳의 레거시 시스템이 OpenSSH 8.2를 쓰고 그것이 양자내성 키 교환을 제공하지 않기 때문입니다. 협상된 알고리즘에는 양쪽의 지원이 필요하며, 시스템에 라이브러리가 로드돼 있다는 것이 특정 연결이 그것을 썼다는 증거는 아닙니다. - 「confirmed」는 증거의 강도이며, 사실을 어떻게 수집했는지로 정해집니다.

보지 못한 것도 똑같이 중요합니다. 같은 실행에서 연결 넷 중 셋은 애플리케이션에 대응시키지 못했습니다. 조회하기 전에 닫혔기 때문입니다. 인벤토리는 이를 갭으로 출력하고, 애플리케이션이 없다는 뜻은 아니라고 알립니다. 다른 세 경우는 다르게 기록됩니다. 수집기가 실행됐지만 무언가를 보지 못했다면 자신의 결과에 갭을 씁니다. 등록 목록을 쓰면 목록에 없는 시스템의 결과는 거부되고, 적재 요약이 그것을 (시스템이 아니라) 결과로 셉니다. 그리고 한 번도 실행되지 않은 수집기는 결과도 갭도 남기지 않으므로, 그런 것은 실행 로그를 시스템 목록과 비교해야만 찾을 수 있습니다. 관측하지 못한 것을 보세요.

결정(사람): 이 관측 범위가 행동에 옮기기에 충분한가, 그리고 갭을 어떻게 할 것인가.

3단계. 무엇을 어떤 순서로 바꿀지 정한다

pqcota가 주는 것: 결정에 쓸 사실, 그리고 상황마다 무엇을 생성할 수 있는지에 대한 설명입니다. 순위를 매기거나 점수를 주거나 추천하지 않습니다. 위험 등급은 일부러 없습니다. 도구가 대신 결정하는 순간 「🔴은 판정이 아니라 관측」이라는 말이 더는 참이 아니게 되기 때문입니다.

무엇을 생성할 수 있는지는 런타임과 버전에 달려 있습니다. 아래 표는 지원 범위를 예의 시스템에 적용해 선택지를 예시한 것입니다. 데모가 실행하는 계획이 아닙니다. 기본 데모는 pay-db에 provider 주입 조치를 생성하고 전달 경로만 보이려고 빈 시험 모듈을 놓습니다. 그 모듈은 암호를 더하지 않습니다. 선택 단계인 실물 provider 단계(DEMO_REAL_PROVIDER=1)는 OpenSSL 3.0–3.4로 관측된 노드를 고르는데, 기본 토폴로지에서는 web-gw이며 실물 provider를 설치합니다.

예의 상황 pqcota가 생성할 수 있는 것
OpenSSL 3.5 이상(pay-app의 OpenSSL) 설정 조각만
OpenSSL 3.0–3.4(web-gw) 설정 조각, 그리고 사용자가 제공하는 provider 모듈의 배치
OpenSSL 1.1.1 이하(pay-db) 없음. 거기서는 설정으로 양자내성 알고리즘을 더할 수 없습니다. 라이브러리 교체는 수동 단계이고 출력도 그렇게 표시합니다
SSH(pay-db) 이 조치들이 다루지 않습니다. 데모의 설명은 그 시스템의 OpenSSH가 양자내성 키 교환을 제공하지 않는다는 것입니다
Java provider JDK에 달려 있습니다. 최근 JDK는 설정만, 그 밖에는 provider 라이브러리와 등록, 지원이 끝난 JDK는 없음

결정(사람): - 어떤 조치를, 어느 시스템에, 어떤 순서로, 언제까지 할 것인가. 기한과 데이터 우선순위는 이 문서가 아니라 사용자가 따르는 기관(규제 기관, 조직의 책임 부서)에서 받으세요. - provider를 쓴다면 어떤 provider를 고르고 그 파일을 어디서 구하는가. 모듈과 기대하는 체크섬은 사용자가 제공합니다. 생성된 플레이북은 놓인 파일을 그 체크섬과 대조하는데, 사용자가 넘겼을 때만 합니다(플레이북을 실행할 때 pqcota_module_sha256 변수로). 넘기지 않으면 그 확인은 건너뜁니다. - pay-db를 어떻게 할 것인가. 그곳으로 가는 TLS 연결이 🟢이 되려면 그쪽 끝이 양자내성 그룹을 지원해야 하고, OpenSSL 1.1.1에서는 라이브러리를 교체해야 합니다. SSH 연결은 그곳의 SSH 소프트웨어에 달려 있으며 별개의 결정입니다.

결정은 계획에 기록합니다. 계획은 사람이 쓰는 파일입니다. pqcota는 계획을 만들지 않고 읽기만 하며, 상황마다 샘플 계획(영문)이 있습니다.

4단계. 변경을 승인하고, 실행하고, 되돌릴 방법을 남긴다

pqcota가 주는 것: - 계획이 확정됐고 승인자의 등록된 공개 키와 맞는 승인 서명이 붙어 있는지 확인합니다. 기본적으로 그렇지 않으면 거부합니다. - 사용자가 고른 자동화 수준의 표준 Ansible로 생성한 파일. provider 주입 조치라면 L1은 대상에 모듈을 놓고, L2(기본)는 설정도 놓고, L3는 계획이 정의한 활성화 단계(예: 재시작)까지 실행합니다. 수준은 자동화가 어디까지 가는지를 정하며, 실제로 무엇이 놓이는지는 조치의 종류에 달려 있습니다. 설정만 하는 조치에는 놓을 모듈이 없고, 수동 단계는 아무것도 놓지 않습니다. - 생성한 변경마다 짝이 되는 제거 파일, 그리고 생성기에 데이터베이스(--dsn)를 주었을 때는 앞서 관측한 상태의 기록.

결정(사람): - 누가 승인하고 누가 승인 키를 보관하는가. pqcota는 서명을 확인할 뿐이고, 조직의 검토 절차는 그 밖의 일입니다. - 확인을 완화하는 옵션을 쓸 것인가. --allow-unverified-approvals는 등록된 키가 없을 때 검증 없이 계속하고, --allow-incomplete는 빈칸이 있는 출력이 종료 코드 0으로 끝나게 합니다. 둘 중 하나라도 쓰면 보고서가 그렇게 밝혀야 합니다. - 파일을 언제 어디에 적용할 것인가. pqcota는 적용하지 않습니다. 사용자가 자신의 도구로 실행하고, 그 도구의 로그가 무엇을 언제 적용했는지의 기록입니다.

이것들을 구분하세요. - 생성기의 종료 코드는 인증서가 아닙니다. 메시지, 사용한 옵션, 기록이 저장됐는지를 읽으세요(자세히). - STAGED로 표시된 기록은 생성기가 변경을 기록했다는 뜻이지 노드에 무엇이 놓였다는 뜻이 아닙니다. - 제거 파일은 계획이 배치한 것을 지웁니다. 이전 배포를 복원하는 것이 아닙니다(FAQ).

5단계. 다시 관측하고, 그것이 증명하는 것을 적는다

pqcota가 주는 것: 새 관측과 이전 관측과의 비교입니다.

그것이 무엇을 증명하는지는 계층에 따라 다릅니다. - Java: provider 체인을 직접 읽을 수 있으므로 새로 등록한 provider가 체인에 나타납니다. - OpenSSL: pqcota는 라이브러리와 그 버전을 관측하고 어떤 provider가 로드됐는지는 관측하지 않습니다. 데모의 선택 단계인 실물 provider 단계(DEMO_REAL_PROVIDER=1, 기본 실행이 아님)에서 시험 노드에 실물 양자내성 provider를 적용하자 openssl list -kem-algorithms의 ML-KEM 항목 수가 0에서 14로 늘었고, 되돌리자 0으로 돌아갔습니다. 그 사이의 다시 관측에서는 변화가 없었습니다. provider 계층을 관측하지 않기 때문이고, 연결도 바뀌지 않았습니다. 연결의 등급은 양쪽이 알고리즘을 지원할 때만 바뀌는데, 데모는 그 토폴로지의 상대편이 OpenSSL 1.1.1이라고 설명합니다. - 연결: 🔴 연결이 🟢이 되려면 양쪽이 모두 양자내성 알고리즘을 지원하고 그 연결이 다시 관측돼야 합니다.

결정(사람): 무엇을 말할 자격이 있는가. 「provider를 배치했고 노드가 그 알고리즘을 나열한다」는 능력에 관한 진술입니다. 「이제 연결이 양자내성 알고리즘을 협상한다」는 그 연결들을 관측해야 합니다. 가진 것이 앞의 것이라면 앞의 것을 쓰세요. 피해야 할 표현은 보고 안내에 있습니다.

그러면 순환이 다시 시작됩니다. 범위, 관측, 결정, 승인, 관측.


누가 무엇을 결정하나

pqcota 사람
무엇을 다루나 사용자가 준 등록 목록과 자산 규칙을 적용 목록과 규칙을 고름
무엇이 쓰이나 관측하고 등급을 매김 해석하고, 관측한 범위가 충분한지 판단
무엇을 보지 못했나 여러 종류의 갭을 기록하고 수를 셈 읽고, 어디에도 기록되지 않는 갭을 쫓음
무엇을 언제 바꾸나 무엇을 생성할 수 있는지 설명 자신의 기한과 우선순위로 결정
승인 서명을 확인 승인하고 키를 보관
변경 적용 파일을 생성 적용하고 로그를 보관
효과가 있었나 관측을 비교 그 비교가 무엇을 증명하는지 결정

다음에 볼 곳

  • 시스템에서 무엇이 실행되고, 어떤 데이터를 수집하고, 어떤 권한이 필요한지는 FAQ.
  • 결과를 보고서로 만드는 방법은 보고 안내.
  • 이 예 전체를 컨테이너에서 돌려 보려면 데모(엔지니어용, Docker 필요).
  • 설치하거나 빌드하려면 빌드 안내.

일반 PQC 진술의 출처

English