Подпишите PDF простым JavaScript
Поскольку API-интерфейс WebCrypto развивается и поддерживается Chrome и Firefox, я хотел бы использовать его для цифровой подписи документа PDF. Вокруг не так много литературы, но я нашел несколько примеров [1] и библиотеку PKI.js [2]. В примерах описан процесс подписания, но в конце возвращается подпись. Я ожидаю, что мой PDF-файл Base64 снова вернется в виде подписанной строки Base64, но, к сожалению, этого не происходит. Насколько мне известно, PKI.js не позволяет подписывать мой Base64 PDF.
Есть ли способ подписать PDF-файл только с помощью JavaScript и API WebCrypto? Закрытый ключ можно ввести в <textarea>
или, что еще лучше, хранится в настройках сертификата браузера.
Base64 PDF (из REST API) → Подписать с помощью JS и сертификата → Подписано Base64 PDF (отправить в REST)
2 ответа
На данный момент WebCrypto API не предоставляет доступ к (Windows) или любым другим хранилищам ключей или локальному устройству шифрования USB/Smartcard.
Также в большинстве сценариев подписания для требования защиты файла PDF в пределах границ сервера не рекомендуется отправлять полный файл PDF в браузер или на сервер API подписи.
Таким образом, рекомендуется создавать хэш PDF для подписи, отправлять хеш в браузер и использовать javascript через расширение браузера для доступа к какому-либо приложению, работающему в локальной системе, для доступа к локальному хранилищу ключей (или USB/Smartcard), а также для создания подписи и отправки обратно (Контейнер PKCS7 или CMS в случае подписи PDF) на сервер, где подпись может быть внедрена обратно в PDF, из которого был создан хеш для подписи и отправлен в браузер или на сервер подписи api.
Для сценариев подписи на основе браузера одним из таких бесплатных расширений Chrome является расширение Signer.Digital chrome. Локальная система (хост, работающий за браузером Chrome в Windows) может быть загружен с сайта https://signer.digital/downloads/Signer.Digital.Chrome.Host.Setup.zip или cNET. После установки этого хоста и перезапуска Chrome автоматически добавит Signer. Цифровое расширение Chrome
Фактическая работа этого расширения иллюстрируется здесь
JavaScript для вызова метода из расширения:
//Calculate Sign for the Hash by Calling function from Extension SignerDigital
SignerDigital.signPdfHash(hash, $("#CertThumbPrint").val(), "SHA-256") //or "SHA256"
.then(
function (signDataResp) {
//Send signDataResp to Server
},
function (errmsg) {
//Send errmsg to server or display the result in browser.
}
);
В случае успеха возвращает подпись pkcs7 в кодировке Base64 - используйте подходящую библиотеку или библиотеку, предоставленную Signer.Digital для вставки знака в pdf
Если Ошибка, возвращает сообщение об ошибке, начиная с "SDHost Error:"
Это технически возможно сделать, на самом деле это один из сценариев, который мы имели в виду, когда создавали PKIjs (вот почему существует этот образец) - https://pkijs.org/examples/PDFexample.html
При этом для подписывания требуется работа с самой структурой PDF, для чего требуется либо собственный синтаксический анализатор, либо изменения существующего (например, pdfjs).
Короче говоря, подписание PDF в браузере потребует много работы, но мы над этим работаем.
Существует PDFSign.js, библиотека, которая может подписывать PDF-файл в браузере. Он использует кузницу, хотя для подписи. Если PKI.js поддерживает отсоединенные подписи pkcs7, тогда легко заменить forge.
Вы можете подписать любой файл (включая pdf) с помощью openpgp.js
https://openpgpjs.org/openpgpjs/doc/
(прокрутите вниз до 'create-and-verify-detached-signatures')
Прочтите файл как Uint8Array и подпишите его своим закрытым ключом.