Как цифровая подпись доказывает, кто подписал
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 можно представить как буквальное «восстановление» хеша. «Действительна» означает «цело и подлинно». «Недействительна» означает, что что-то изменилось или был использован неверный ключ, и честный ответ — недействительна.
- Prepare the inputRSA and ECDSA hash the document to a short, fixed-length fingerprint; EdDSA signs the content directly and hashes it internally. Either way, any change to the bytes changes what is signed.
- Sign with the private keyThe signer applies a private-key operation to that input — the hash for RSA and ECDSA, the content for EdDSA. The output is the signature value; only the private-key holder could have produced it.
- Reconstruct the inputThe verifier independently rebuilds the same input from the content — a recomputed hash for RSA and ECDSA, the content itself for EdDSA. This is what the verify operation checks against.
- Verify with the public keyThe verifier runs the algorithm's verify operation on the public key, the signature value, and that input. The same shape works for RSA, ECDSA, and EdDSA.
- Accept or rejectThe verify operation returns valid or invalid. Valid means the bytes are intact and the private-key holder signed them. Otherwise the result is invalid — no guessing.
В реальном PDF NextPDF не вдавливает печать поверх видимой страницы — он вдавливает её поверх объявленного диапазона байтов и упаковывает подпись как отделённый объект CMS (Spec: RFC 5652RFC 5652), помещённый внутрь файла (Spec: ISO 32000-2, §12.8ISO 32000-2 §12.8). Один нюанс важен: подписант не подписывает сырой хеш содержимого напрямую. Он подписывает небольшой набор подписанных атрибутов, которые включают хеш содержимого, так что время, тип содержимого и идентификатор сертификата подписанта запечатаны вместе. Где живут эти байты и почему диапазон имеет именно такую форму — тема страницы Как подписи располагаются в PDF.
Пока что математика доказывает, что некий ключ подписал эти байты. Она ничего не говорит о том, чей ключ. Именно этот пробел и заполняет сертификат. Сертификат — это сам по себе подписанное утверждение — от удостоверяющего центра, — что этот открытый ключ принадлежит этому именованному субъекту. Доверять ему — значит следовать по цепочке от сертификата подписанта вверх до центра, которому вы решили доверять, проверяя действительность каждого звена по пути (Spec: RFC 5280, §6RFC 5280 §6). Без этой цепочки «подписано» анонимно. С ней «подписано» имеет имя.
Последняя часть — это когда. Подпись может встроить собственное заявленное подписантом время, но часы, которыми вы не управляете, — это утверждение, а не доказательство. Метка времени от удостоверяющего центра меток времени (TSA) привязывает хеш подписи к моменту, заверенный стороной, не заинтересованной в документе (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: the hash-and-sign mechanism described here, packaged as a detached CMS SignedData object, plus certificate-path validation against a trust anchor you supply. |
| Pro | Adds PAdES B-T — a verified RFC 3161 trusted timestamp on the signature value, so the “when” is attested rather than self-claimed. |
| Enterprise | Adds the long-term profiles (B-LT, B-LTA): embedded validation material and document timestamps that keep the identity and time proofs answerable for years. |
Связанные документы
Заголовок раздела «Связанные документы»- Как подписи располагаются в PDF — где значение подписи и его диапазон байтов на самом деле живут в файле.
- Правильная проверка подписи — полный набор проверок, которые должен прогнать проверяющий, помимо математики на этой странице.
- Метки времени и доверенное время — что доказывает метка времени RFC 3161, и почему собственные часы подписанта — это не оно.
- Базовые профили PAdES — какой профиль накладывает идентичность, время и долговременные материалы на этот фундамент.
Глоссарий
Заголовок раздела «Глоссарий»- Хеш (дайджест) — короткий отпечаток данных фиксированной длины от криптографической хеш-функции; любое изменение данных меняет его полностью.
- Пара ключей — связанные закрытый ключ (которым владеет только подписант) и открытый ключ (распространяемый свободно); только закрытый ключ может подписывать, и только соответствующий открытый ключ может проверять.
- Подписание — применение операции с закрытым ключом к входу, который определяет алгоритм: хешу содержимого для RSA и ECDSA или содержимому напрямую для EdDSA (который хеширует внутренне). В PDF этим содержимым являются подписанные атрибуты, включающие хеш документа. Результат — это значение подписи.
- Проверка — восстановление того же входа (пересчитанного хеша или содержимого напрямую для EdDSA), затем запуск операции проверки алгоритма над открытым ключом, значением подписи и этим входом, чтобы получить ответ «действительна или недействительна».
- Значение подписи — байты, которые производит операция с закрытым ключом; то, что проверяющий сверяет с заново восстановленным входом алгоритма (дайджестом для RSA и ECDSA, самим содержимым для EdDSA).
- Сертификат — подписанное утверждение, связывающее открытый ключ с именованной идентичностью; доверенное за счёт сцепления с центром, который вы признаёте (RFC 5280 §6).
- Якорь доверия (trust anchor) — удостоверяющий центр, которому вы решили доверять; корень приемлемой цепочки сертификатов.
- Метка времени (RFC 3161) — подписанный токен от удостоверяющего центра меток времени, привязывающий хеш к значению времени, обеспечивающий доверенное доказательство того, когда.
- CMS SignedData — структура Cryptographic Message Syntax (RFC 5652), которая несёт значение подписи и сертификат подписанта.
- PAdES — PDF Advanced Electronic Signatures: семейство профилей ETSI для подписания PDF. Подробно рассмотрено на страницах о подписании.