서명을 올바르게 검증하는 방법
Spec: RFC 5280, §6 RFC 5280 §6 Spec: RFC 6960 RFC 6960 Spec: RFC 5652 RFC 5652 Evidence: Test-backed
한눈에 보기
섹션 제목: “한눈에 보기”“서명이 유효하다”는 보통 한 가지, 즉 수학적 계산이 맞아떨어졌다는 것만 확인했다는 뜻입니다. 올바른 검증은 최소한 다섯 가지 독립적인 항목을 확인하며, 그중 어느 하나라도 실패하면 초록색 체크 표시가 무의미해질 수 있습니다. 이 페이지는 전체 검사 집합을 정리하고, 부분적인 답이 왜 위험한 답인지 설명합니다.
이것이 중요한 이유
섹션 제목: “이것이 중요한 이유”단일 불리언 값은 이 주제 전체에서 가장 위험한 출력입니다. 그 값은 독자가 “유효함”을 “신뢰할 수 있음”으로 받아들이도록 유도하지만, “유효함”은 단지 바이트가 변경되지 않았다는 의미일 뿐일 수 있습니다 — 3년 전에 만료되었고, 지난달에 폐지되었으며, 여러분이 인정하는 어떤 기관에도 연결되지 않는 인증서의 키로 말입니다. 이들 각각은 별개의 검사입니다. 불리언 하나만 보고하는 소프트웨어는 어떤 검사가 중요한지를 조용히 결정해 버린 것이며, 그 결정을 여러분 대신 내린 것입니다. 규제 또는 계약 환경에서 도구가 가장 저렴한 속성만 검증했다면 “도구가 유효하다고 했다”는 것은 변명이 되지 않습니다.
완전한 검증은 다섯 개의 별개 질문에 답합니다. 이들은 독립적입니다 — 하나를 통과했다고 해서 나머지에 대해서는 아무것도 말해 주지 않습니다.
- 무결성 — 서명된 바이트가 여전히 서명이 포괄하는 값으로 해시됩니까? (바이트 범위 다이제스트를 다시 계산해 비교합니다.)
- 진정성 — 암호화 서명이 서명된 속성에 대해 서명 인증서의 공개 키로 검증됩니까?
- 인증서 경로 — 그 인증서가 여러분이 선택한 신뢰 앵커까지 연결되며, 모든 연결 고리가 유효합니까?
- 시간 — 해당 시점에 인증서가 유효 기간 내에 있었으며, 그 시간이 자체 주장된 것이 아니라 신뢰된 것입니까?
- 폐지 — 그 시점에 인증서가 폐지되지 않았음이, 실제로 확보할 수 있거나 임베드된 증거(OCSP/CRL)로 확인됩니까?
다섯 가지를 모두 수행하지 않은 “유효함”은 완전한 답처럼 보이는 불완전한 답입니다.
NextPDF의 접근 방식
섹션 제목: “NextPDF의 접근 방식”NextPDF의 입장은 각 질문이 별개이며 각각에 명시적으로 답해야 한다는 것입니다. 질문은 결코 하나의 낙관적인 플래그로 뭉뚱그려지지 않으며, 검사가 번거롭다는 이유로 조용히 건너뛰는 일도 결코 없습니다. 이는 테스트로 강제됩니다. 이 페이지가 표준 기반이 아니라 테스트 기반으로 표시된 이유가 바로 이것입니다. 즉, 이 동작은 조항으로만 논증되는 것이 아니라 테스트 스위트로 계속 보장됩니다.
무결성과 진정성은 종단 간 방식으로 테스트됩니다. 알려진 인증서가 실제 서명된 속성 구조에 서명하고, 테스트 스위트가 여러 시간 벡터에 걸쳐 일치하는 공개 키로 서명을 검증합니다. 따라서 정규 구조를 깨뜨리는 변경은 테스트를 깨뜨립니다. 인증서 경로 검증은 서명 바이트를 의도적으로 조작해, 그 결과가 구조화된 이유와 함께 유효하지 않다고 단언하는 테스트로 유지됩니다 — 삼켜진 예외가 아니라 명시적으로 기록된 실패로 말입니다. 타임스탬프 토큰 검증은 개별 단계 — 디코드, 서명자 정보, 서명된 속성, 메시지 다이제스트, 인증서 바인딩, 키 사용, 서명, produced-at — 로 나뉘며, 각 단계가 개별적으로 테스트되므로 “타임스탬프가 검증됨”은 모든 단계가 검증되었음을 의미합니다. 폐지 소프트 실패(응답자에게 도달할 수 없음)는 코드와 테스트 모두에서 확정적인 “폐지됨”과 구분됩니다. 이 둘은 결코 같은 답으로 혼동되지 않습니다.
- Integrity Recompute the byte-range digest and compare it to the value the signature covers.
- Authenticity Verify the cryptographic signature against the certificate’s public key, over the signed attributes — not the raw content.
- Certificate path Build and validate the chain to a trust anchor you chose; every link’s signature, validity, and constraints must hold.
- Time Confirm the certificate was valid at the relevant instant, and that the instant is trusted time, not the signer’s clock.
- Revocation Confirm the certificate was not revoked at that time, using obtainable or embedded OCSP/CRL evidence.
증거가 말하는 것
섹션 제목: “증거가 말하는 것”Evidence: Test-backed 이 동작은 테스트로 고정되어 있으며, 그 테스트는 표준이 요구하는 바를 구현합니다.
무결성 검사는 Spec: ISO 32000-2, §12.8.1 ISO 32000-2 §12.8.1 입니다. 다이제스트가 바이트 범위에 대해 다시 계산되어 저장된 값과 비교되며, 조금이라도 차이가 있으면 서명이 무효임을 의미합니다. 서명된 속성에 대한 진정성은 실제 서명된 속성 집합에 서명하고 여러 시간 벡터에 걸쳐 일치하는 공개 키로 이를 검증하는 통합 테스트로 다룹니다. 인증서 경로 질문은
Spec: RFC 5280, §6.1 RFC 5280 §6.1 입니다. 유효한 경로는 신뢰
앵커에서 시작해야 하며, Spec: RFC 5280, §6.2 RFC 5280 §6.2 은 그 알고리즘이
경로가 유효하기 위한 최소 조건을 정의한다고 명시합니다 — 경로 검증기
단위 테스트는 조작된 서명이 명시적인 이유와 함께 valid = false를 산출하며 결코
조용히 수락되지 않음을 단언합니다.
폐지 순서는 Spec: RFC 6960, §3.2 RFC 6960 §3.2 입니다. 클라이언트는 서명된 폐지 응답을 유효한 것으로 수락하기 전에 그 응답 자체의 서명이 유효하며 서명자가 현재 권한을 부여받았음을 확인해야 합니다(SHALL) — 그리고 Spec: RFC 6960, §4.2.2.2 RFC 6960 §4.2.2.2 은 그 권한 부여를 해당 CA가 직접 발급한 id-kp-OCSPSigning 위임으로 정의합니다. 따라서 권한을 부여받고 검증 가능한 서명자에 대해 그 자체가 검증되지 않은 폐지 답변은 무의미합니다. 인증서 바인딩 검사는 Spec: RFC 5035, §5.4.2 RFC 5035 §5.4.2 입니다. 서명된 signing-certificate-v2 속성의 인증서 해시가 서명을 검증하는 데 사용된 인증서와 일치하지 않으면 그 서명은 무효로 간주되어야 합니다. 이는 서명이 공격자가 선택한 인증서로 검증되는 대체 허점을 막습니다. 타임스탬프 자체의 토큰은 Spec: RFC 5652 RFC 5652 방식으로 CMS 객체로서 단계별로 검증되며, 각 단계가 개별적으로 테스트됩니다.
실용적 예시
섹션 제목: “실용적 예시”핵심은 API 호출이 아닙니다. 결과에 따라 행동하기 전에 답할 수 있어야 하는 질문들입니다. 이를 검토 과정에서 여러분이 책임져야 할 체크리스트로 다루십시오.
<?php
declare(strict_types=1);
// A correct validation produces a structured outcome, not one boolean.// Before you trust a signature, you must be able to answer ALL of these://// integrity : Does the byte-range digest still match? (tamper check)// authenticity: Does the signature verify over the SIGNED ATTRIBUTES,// not just the content?// path : Does the certificate chain to a trust anchor YOU chose,// with every link valid at the relevant time?// time : Is the relevant time TRUSTED (a timestamp), or merely the// signer's self-asserted clock?// revocation : Was the certificate not revoked at that time, by evidence// you obtained or that the document embedded?//// "valid: true" without an answer to every line above is an incomplete// result. A path-validation outcome carries a `valid` flag AND a structured// `reasons` list precisely so a failure says WHY — never a bare false.어느 항목이라도 “모르겠다”라면, 정직한 상태는 “유효함”이 아닙니다. 그것은 “아직 결정되지 않음”이며 — 이 둘을 같은 것으로 취급하는 것이야말로 이 페이지가 방지하고자 하는 오류입니다.
흔한 오해
섹션 제목: “흔한 오해”함정은 “암호학적으로 유효함”을 “신뢰할 수 있음”과 동일시하는 것입니다. 무결성과 진정성은 함께 이 바이트가 이 키의 소유자에 의해 서명되었다는 것만 증명합니다. 이들은 그 키의 인증서가 신뢰되었는지, 유효 기간 내였는지, 폐지되지 않았는지에 대해서는 아무것도 말해 주지 않습니다. 자체 생성한 인증서로 서명된 문서는 “암호학적으로 유효함”이면서도 아무런 가치가 없을 수 있습니다. 반대 함정은 불확정 폐지 검사(응답자 오프라인)를 통과 — 또는 실패 — 로 취급하는 것입니다. 그것은 둘 중 어느 것도 아닙니다. 그것은 알 수 없음이며, 올바른 검증기는 어느 방향으로든 추측하기보다 이를 알 수 없음으로 보고합니다. 다섯 가지 검사 중 어느 것이 실제로 실행되었는지를 숨기는 초록색 체크 표시는 검증 결과가 아닙니다. 그것은 다른 누군가가 여러분을 대신해 내린 결정입니다.
한계와 경계
섹션 제목: “한계와 경계”NextPDF는 구조적 검사와 암호학적 검사를 수행하고 테스트합니다. 하지만 여러분의 신뢰 앵커를 선택하거나 그 위에 적용되는 정책을 보장하지는 않습니다. 어떤 인증서를 신뢰할지는 엔진이 내릴 수 없는 배포 결정입니다. 신뢰하지 말았어야 할 앵커까지 검증되는 체인은 여전히 여러분이 의존할 수 없는 검증입니다. 폐지 증거는 확보할 수 있거나 임베드되어 있을 때만 확인할 수 있습니다. 오프라인 응답자는 “불확정”을 산출하며, 그것을 판정으로 바꾸는 것은 엔진의 선택이 아니라 정책의 선택입니다. 이 페이지는 법적 충분성이 아니라 검사 집합을 설명합니다. 검증된 서명이 특정한 법적 효력을 갖는지 여부는 인증서, 서명자, 관할권, 그리고 의무에 따라 달라집니다. 임베드된 증거가 시간이 지나도 이러한 검사에 답할 수 있는 상태로 유지하는 방법은 장기 검증에서 다룹니다. 무결성 검사 이면의 바이트 범위 메커니즘은 서명이 PDF에 자리 잡는 방식에 있습니다.
검증 영역의 티어별 제공 범위:
| Edition | Availability |
|---|---|
| Core | 서명된 속성에 대한 무결성과 진정성, 그리고 공급된 신뢰 앵커에 대한 RFC 5280 §6 인증서 경로 검증. |
| Pro | RFC 3161 타임스탬프 토큰 검증을 추가하여, 신뢰된 시간 질문을 독립적으로 검사되는 단계들로 분해하여 다룹니다. |
| Enterprise | 폐지 평가(OCSP/CRL)와 임베드된 장기 자료에 대한 검증을 추가하며, 불확정 결과를 확정적 결과와 구분합니다. |
관련 문서
섹션 제목: “관련 문서”- 장기 검증 — 임베드된 증거가 몇 년이 지난 후에도 시간 및 폐지 검사에 답할 수 있는 상태로 유지하는 방법.
- 서명이 PDF에 자리 잡는 방식 — 무결성 검사가 다시 계산하는 바이트 범위 메커니즘.
- 타임스탬프와 신뢰된 시간 — “시간” 질문을 서명자의 시계가 아닌 다른 근거로 답할 수 있게 만드는 것.
용어집
섹션 제목: “용어집”- 무결성 검사 — 바이트 범위 다이제스트를 다시 계산하여 서명이 포괄하는 값과 비교하는 것.
- 진정성 검사 — 서명된 속성에 대해 암호화 서명을 서명 인증서의 공개 키로 검증하는 것.
- 서명된 속성 — 서명이 실제로 계산되는 대상인 인증된 CMS 속성(content-type, message-digest, signing-time, signing-certificate-v2).
- 인증서 경로 검증 — 서명 인증서에서 선택된 신뢰 앵커까지의 체인을 구성하고 검사하는 것(RFC 5280 §6).
- 신뢰 앵커 — 여러분이 신뢰하기로 결정한 인증 기관. 허용 가능한 경로의 루트.
- 폐지 검사 — OCSP 또는 CRL을 통해 해당 시점에 인증서가 폐지되었는지 여부를 판정하는 것.
- 불확정 — 증거를 얻을 수 없어 “양호”도 “폐지됨”도 아닌 폐지 결과. 통과도 실패도 아닙니다.