디지털 서명이 누가 서명했는지 증명하는 방법
Spec: RFC 5652RFC 5652Spec: RFC 5280, §6RFC 5280 §6Spec: RFC 3161, §1RFC 3161 §1
한눈에 보기
섹션 제목: “한눈에 보기”디지털 서명은 세 가지를 하며, 처음부터 그것들을 따로 두는 것이 좋습니다. 그것은 바이트가 변경되지 않았음을 증명하고, 누가 서명했는지를 증명하며 — 약간의 도움을 받아 — 언제 서명했는지를 증명합니다. 이 페이지는 그 개념을 무에서부터 쌓아 올려, 암호학이 더 이상 블랙박스가 아니도록 합니다.
이것이 중요한 이유
섹션 제목: “이것이 중요한 이유”“서명됨”은 사람들이 결정을 거는 단어입니다. 계약서, 청구서, 누군가가 실행할 소프트웨어의 릴리스 노트. 어떤 도구가 초록색 체크 표시를 띄웠다는 것만 안다면, 여러분은 실제로 무엇이 증명되었는지 알지 못합니다. 바이트가 온전하다는 증명은 있지만 누구의 키가 서명했는지는 전혀 모를 수 있습니다. 진짜 서명자는 있지만 몇 년 전에 만료된 인증서일 수 있습니다. 그 조각들을 이해하는 것이 유효한 서명이 무엇을 의미하는지 — 그리고 그에 못지않게 유용하게, 무엇을 의미하지 않는지 — 를 정확하게 말할 수 있게 해 줍니다.
봉인이 봉투 덮개에 눌러 찍힌, 변조가 드러나는 봉투를 떠올려 보십시오.
- 봉인은 한 사람에게 고유하며 사실상 위조가 불가능합니다. 누구나 그것을 알아볼 수 있지만, 그것을 만들 수 있는 사람은 소유자뿐입니다. 그것이 키 쌍입니다. 여러분만이 가진 비공개 키와, 누구나 볼 수 있는 공개 키입니다.
- 여러분은 봉인을 문서 전체에 누르지 않습니다. 그것의 작고 위조할 수 없는 요약 — 해시 — 위에 누릅니다. 문서의 한 바이트를 바꾸면 그 요약이 완전히 바뀌므로, 봉인이 더 이상 맞지 않습니다.
- 서명은 여러분의 비공개 키로 문서에 대한 서명을 만들어 내는 것입니다 — RSA와 ECDSA의 경우 해시에 대해, 또는 EdDSA의 경우 내부에서 자체 해싱을 하는 콘텐츠 자체에 대해. 검증은 여러분의 공개 키, 서명, 그리고 같은 콘텐츠(해시로, 또는 직접)로 알고리즘의 확인을 실행하는 것입니다 — 그것은 유효 또는 무효를 반환합니다. 둘을 잇는 것은 신뢰가 아니라 수학입니다.
- 인증서는 이것이 누구의 봉인인지를 말하는 부분입니다. 그것이 없으면, 여러분은 어떤 키가 바이트에 서명했음을 증명한 것이지, 그 키가 특정한 누구에게 속한다는 것은 증명하지 못한 것입니다.
- 타임스탬프는 언제를 말하는 부분입니다. 서명자 자신의 시계는 그저 주장일 뿐이며, 신뢰할 수 있는 시점은 외부 기관에서 옵니다.
NextPDF가 이를 다루는 방식
섹션 제목: “NextPDF가 이를 다루는 방식”해시에서 시작하십시오. 다른 모든 것이 그 위에 서 있기 때문입니다. 암호학적 해시 함수는 임의의 양의 데이터를 읽어 짧고 고정 길이인 지문을 생성합니다 — PDF 서명의 경우 일반적으로 256비트 값입니다. 두 가지 속성이 그것을 유용하게 만듭니다. 같은 입력은 항상 같은 지문을 산출하고, 같은 지문을 갖는 다른 입력을 찾는 것은 실행 불가능합니다. 그래서 해시는 문서의 충실한 대역입니다. 두 해시가 일치하면, 바이트가 일치합니다.
이제 키 쌍입니다. 비공개 키와 공개 키는 수학적으로 연결되어 있지만, 어떤 실용적인 시간 안에서도 하나로부터 다른 하나를 도출할 수 없습니다. 비공개 키만이 유효한 서명을 생성할 수 있고, 일치하는 공개 키만이 그것을 확인할 수 있습니다. 서명은 그 비대칭성을 사용합니다. 서명자는 선택한 알고리즘이 정의하는 입력에 비공개 키 연산을 적용합니다 — RSA와 ECDSA의 경우 콘텐츠의 해시, 또는 내부에서 해싱하는 EdDSA의 경우 콘텐츠 직접. 그 결과가 서명 값입니다. 비공개 키의 보유자만이 그것을 생성할 수 있었기 때문에, 그리고 그것이 이 콘텐츠에 결속되어 있기 때문에, 그것은 두 가지를 동시에 증명합니다 — 보유자가 서명했다는 것, 그리고 바이트가 그 이후로 움직이지 않았다는 것.
검증은 그 논리를 거울처럼 반영합니다. 검증자는 같은 입력을 재구성합니다 — RSA와 ECDSA의 경우 문서를 해싱하고, EdDSA의 경우 콘텐츠를 직접 취합니다 — 그런 다음 공개 키, 서명 값, 그리고 그 입력에 서명 알고리즘의 검증 연산을 실행합니다. 그 연산은 유효 또는 무효를 반환합니다 — 그리고 이것은 알고리즘이 RSA든, ECDSA든, EdDSA든 같은 형태이며, 오직 RSA만이 문자 그대로 해시를 “복원”하는 것으로 그려질 수 있더라도 그렇습니다. 유효는 온전하고 진정하다는 뜻입니다. 무효는 무언가가 변경되었거나 잘못된 키가 사용되었다는 뜻이며, 정직한 답은 무효입니다.
- 입력 준비RSA와 ECDSA는 문서를 짧고 고정 길이인 지문으로 해싱합니다; EdDSA는 콘텐츠에 직접 서명하고 내부에서 해싱합니다. 어느 쪽이든, 바이트의 어떤 변경도 서명되는 것을 바꿉니다.
- 비공개 키로 서명서명자는 그 입력에 비공개 키 연산을 적용합니다 — RSA와 ECDSA의 경우 해시, EdDSA의 경우 콘텐츠. 출력은 서명 값입니다; 비공개 키 보유자만이 그것을 생성할 수 있었습니다.
- 입력 재구성검증자는 콘텐츠로부터 같은 입력을 독립적으로 다시 만듭니다 — RSA와 ECDSA의 경우 다시 계산한 해시, EdDSA의 경우 콘텐츠 자체. 이것이 검증 연산이 대조하는 것입니다.
- 공개 키로 검증검증자는 공개 키, 서명 값, 그리고 그 입력에 알고리즘의 검증 연산을 실행합니다. 같은 형태가 RSA, ECDSA, EdDSA에 작동합니다.
- 수락 또는 거부검증 연산은 유효 또는 무효를 반환합니다. 유효는 바이트가 온전하고 비공개 키 보유자가 서명했다는 뜻입니다. 그렇지 않으면 결과는 무효입니다 — 추측은 없습니다.
실제 PDF에서, NextPDF는 보이는 페이지 위에 봉인을 누르지 않습니다 — 그것은 선언된 바이트 범위에 봉인을 누르고, 서명을 분리된 CMS 객체 (Spec: RFC 5652RFC 5652)로 패키징하여 파일 안에 (Spec: ISO 32000-2, §12.8ISO 32000-2 §12.8) 배치합니다. 한 가지 정교한 점이 중요합니다. 서명자는 원시 콘텐츠 해시에 직접 서명하지 않습니다. 그것은 콘텐츠의 해시를 포함하는 작은 서명 속성 집합에 서명하므로, 시간, 콘텐츠 유형, 그리고 서명자의 인증서 식별자가 모두 함께 봉인됩니다. 그 바이트가 어디에 있는지, 그리고 그 범위가 왜 그런 형태인지는 PDF 안에서 서명이 자리하는 방식의 주제입니다.
지금까지, 수학은 어떤 키가 이 바이트에 서명했음을 증명합니다. 그것은 누구의 키인지는 아무것도 말하지 않습니다. 그 간극이 바로 인증서가 채우는 것입니다. 인증서는 그 자체로 — 인증 기관으로부터의 — 서명된 진술로, 이 공개 키가 이 이름이 명시된 주체에게 속한다는 것입니다. 그것을 신뢰한다는 것은 서명자의 인증서에서부터 여러분이 신뢰하기로 결정한 기관까지 체인을 따라가며, 그 과정에서 모든 연결 고리의 유효성을 확인하는 것입니다 (Spec: RFC 5280, §6RFC 5280 §6). 그 체인이 없으면 “서명됨”은 익명입니다. 그것이 있으면 “서명됨”은 이름을 갖습니다.
마지막 조각은 언제입니다. 서명은 서명자 자신이 주장하는 시간을 내장할 수 있지만, 여러분이 통제하지 않는 시계는 증명이 아니라 주장입니다. 타임스탬프 기관의 타임스탬프는 서명의 해시를, 문서에 아무 이해관계가 없는 당사자가 입증한 어떤 시점에 결속합니다(Spec: RFC 3161, §1RFC 3161 §1). 그것이 바로 서명자의 인증서가 만료된 뒤에도 서명이 의미를 유지하게 하는 것입니다. 인증서가 여전히 유효했을 때 서명이 존재했음을 보일 수 있기 때문입니다. 더 깊은 설명은 타임스탬프와 신뢰할 수 있는 시점에 있습니다.
실용 예제
섹션 제목: “실용 예제”아래 형태들은 평이하게 작성된 개념적 연산입니다. 요점은 API 호출이 아닙니다 — 그것은 서명과 검증이 거울상이라는 것, 그리고 변조된 바이트가 구조적으로 일치를 깨뜨린다는 것을 보는 것입니다.
<?php
declare(strict_types=1);
// SIGN — the holder of the private key seals the content.// RSA and ECDSA sign a hash; EdDSA signs the content directly (hashing inside).$signingInput = sign_input($content); // a digest for RSA/ECDSA, the content for EdDSA$signatureValue = private_key_transform( // only the key holder can do this privateKey: $signerPrivateKey, input: $signingInput,);
// VERIFY — anyone with the public key runs the algorithm's check.$recomputedInput = sign_input($content); // verifier rebuilds the same input$intactAndAuthentic = signature_verify( // RSA, ECDSA, EdDSA — same shape publicKey: $signerPublicKey, // taken from the certificate signatureValue: $signatureValue, input: $recomputedInput, // the freshly reconstructed input);// true -> bytes unchanged AND signed by the private-key holder// false -> a byte changed, or the wrong key — the honest answer is "invalid"
// The certificate answers a SEPARATE question: whose public key is this?// The timestamp answers ANOTHER: when did this signature exist?// "intact + authentic" alone proves neither identity nor time.여전히 검증을 통과하는 변경을 위조하는 것은 계산적으로 실행 불가능합니다. 해시는 콘텐츠를 충실하게 담으므로, 콘텐츠를 바꾸면 해시가 바뀌고, 검증 연산은 그것을 거부합니다 — 선택된 함수가 비현실적으로 만들도록 설계된 해시 충돌을 찾는 것이 아니라면.
흔한 오해
섹션 제목: “흔한 오해”자주 하는 실수는 “유효한 서명”을 “신뢰할 수 있는 문서”로 읽는 것입니다. 그것들은 같은 문장이 아닙니다. 암호학은 바이트가 온전하다는 것과 비공개 키 보유자가 서명했다는 것을 증명합니다 — 그 이상은 아닙니다. 여러분이 한 번도 들어 본 적 없는 키로 서명되고, 여러분이 인식하는 어떤 기관에 의해서도 입증되지 않은 문서는, 흠잡을 데 없이 “유효”하면서도 아무 가치가 없을 수 있습니다. 신원은 인증서와 그 체인에서 옵니다; 시점은 신뢰할 수 있는 타임스탬프에서 옵니다. 이 모든 것을 조용히 하나의 불리언으로 접어 넣는 초록색 체크 표시는, 여러분을 대신하여 어떤 질문이 중요한지 결정한 것입니다. 그 조각들을 아는 것이 나머지를 물을 수 있게 해 줍니다.
한계와 경계
섹션 제목: “한계와 경계”이 페이지는 디지털 서명의 개념을 설명하지, 전체 검증 절차를 설명하지 않습니다. 여기서의 수학은 무결성과 진정성을 증명합니다. 그것은 그 자체만으로는, 서명 인증서가 여러분이 생각하는 사람에게 발급되었는지, 서명 시점에 유효했는지, 또는 나중에 폐기되었는지를 알려 주지 않습니다 — 그것들은 인증서 경로와 폐기 질문이며, 올바른 검증은 그 모두를 실행합니다. 완전한 확인 집합은 서명을 올바르게 검증하기에 있습니다.
NextPDF는 서명 구조를 빌드하고 암호학적 확인을 수행합니다. 그것은 여러분의 신뢰 앵커를 선택하거나, 어떤 인증 기관을 보증하거나, 서명의 법적 효력을 결정하지 않습니다 — 그것들은 여러분의 배포, 인증서, 그리고 관할권에 달려 있습니다. 엔진은 메커니즘을 증명하고, 그 위의 신뢰 결정은 여러분의 것입니다.
엔진이 무엇을 출시하는지는, 계층별로, 이 토대로부터 바깥으로 빌드됩니다.
| Edition | Availability |
|---|---|
| Core | PAdES B-B: 여기서 설명한 해시-앤-사인 메커니즘으로, 분리된 CMS SignedData 객체로 패키징되며, 여러분이 제공하는 신뢰 앵커에 대한 인증서 경로 검증을 더합니다. |
| Pro | PAdES B-T를 더합니다 — 서명 값에 대한 검증된 RFC 3161 신뢰할 수 있는 타임스탬프로, “언제”가 자가 주장이 아니라 입증됩니다. |
| Enterprise | 장기 프로파일(B-LT, B-LTA)을 더합니다: 내장된 검증 자료와 문서 타임스탬프로, 신원 및 시점 증명을 수년 동안 답할 수 있게 유지합니다. |
관련 문서
섹션 제목: “관련 문서”- PDF 안에서 서명이 자리하는 방식 — 서명 값과 그 바이트 범위가 파일 안 어디에 실제로 자리하는지.
- 서명을 올바르게 검증하기 — 이 페이지의 수학을 넘어, 검증자가 실행해야 하는 확인의 전체 집합.
- 타임스탬프와 신뢰할 수 있는 시점 — RFC 3161 타임스탬프가 무엇을 증명하는지, 그리고 서명자 자신의 시계가 왜 그것이 아닌지.
- PAdES 베이스라인 프로파일 — 어떤 프로파일이 신원, 시점, 그리고 장기 자료를 이 토대 위에 층으로 얹는지.
용어집
섹션 제목: “용어집”- 해시(다이제스트) — 암호학적 해시 함수가 만든, 데이터의 짧고 고정 길이인 지문입니다; 데이터의 어떤 변경도 그것을 완전히 바꿉니다.
- 키 쌍 — 연결된 비공개 키(서명자만 보유)와 공개 키(자유롭게 공유)입니다; 비공개 키만이 서명할 수 있고, 일치하는 공개 키만이 검증할 수 있습니다.
- 서명 — 알고리즘이 정의하는 입력에 비공개 키 연산을 적용하는 것입니다: RSA와 ECDSA의 경우 콘텐츠의 해시, 또는 EdDSA의 경우 콘텐츠 직접(내부에서 해싱). PDF에서, 그 콘텐츠는 문서의 해시를 포함하는 서명 속성입니다. 그 결과가 서명 값입니다.
- 검증 — 같은 입력(다시 계산한 해시, 또는 EdDSA의 경우 콘텐츠 직접)을 재구성한 다음, 공개 키, 서명 값, 그리고 그 입력에 알고리즘의 검증 연산을 실행하여 유효 또는 무효 답을 얻는 것입니다.
- 서명 값 — 비공개 키 연산이 생성하는 바이트입니다; 검증자가 새로 재구성한 알고리즘 입력(RSA와 ECDSA의 경우 다이제스트, EdDSA의 경우 콘텐츠 자체)에 대조하는 것입니다.
- 인증서 — 공개 키를 이름이 명시된 신원에 결속하는 서명된 진술입니다; 여러분이 수락하는 기관으로 체인을 이어 신뢰됩니다(RFC 5280 §6).
- 신뢰 앵커 — 여러분이 신뢰하기로 결정한 인증 기관입니다; 수용 가능한 인증서 체인의 루트입니다.
- 타임스탬프(RFC 3161) — 타임스탬프 기관의 서명된 토큰으로, 해시를 시간 값에 결속하여 언제에 대한 신뢰할 수 있는 증명을 제공합니다.
- CMS SignedData — 서명 값과 서명자의 인증서를 담는 Cryptographic Message Syntax(RFC 5652) 구조입니다.
- PAdES — PDF Advanced Electronic Signatures: PDF 서명을 위한 ETSI 프로파일 계열입니다. 서명 페이지에서 깊이 다룹니다.