Вопрос или проблема
Мы разрабатываем функциональность для нашего приложения, которая позволяет цифровым образом подписывать документ .pdf. Это можно реализовать тремя способами:
- С использованием сертификата .pfx.
- С использованием одного из сертификатов, установленных на компьютере пользователя.
- С использованием USB-токена (также подключенного к компьютеру пользователя).
На данный момент мы реализовали только первый способ. Теперь у нас возникают проблемы с реализацией второго способа. Поскольку наше приложение работает на бэкенде Java и фронтенде Angular, у нас нет возможности получить сертификаты, установленные на компьютере пользователя. Я читал, что что-то подобное можно было бы сделать с помощью Java Applet, но поскольку они устарели много лет назад, мне интересно, есть ли более современное решение.
Существует ли способ мы сможем добиться этого с помощью имеющихся у нас инструментов? Возможно, есть решение для этой проблемы на Angular?
Если ваш вопрос для сценария (2) заключается в том, как получить файл с локального компьютера, то (java) бэкенд не имеет значения – он не имеет доступа к компьютеру пользователя.
Если Angular приложение работает в браузере, то ответ – НЕТ. Приложения, работающие в браузере, не имеют доступа к локальной файловой системе, если вы не используете функцию загрузки файлов браузера и не попросите пользователя указать файл и загрузить его (на бэкенд).
Если Angular приложение работает локально на компьютере (поскольку вы упаковали его на Node и установили это на компьютере), тогда ответ – ДА, так как у вас будет (определенный доступ) к локальной файловой системе. Тогда вопрос: имеет ли пользователь, который запускает приложение Node разрешение видеть, где хранится этот сертификат. (Как ваше приложение знает, где искать?)
Ответ или решение
Для реализации функциональности цифровой подписи PDF-документов с использованием сертификатов, установленных на компьютер пользователя, необходимо учитывать ограничения, связанные с окружением браузера и архитектурой вашего приложения (Java backend и Angular frontend).
Описание ситуации
На данный момент вы достигли успеха с первым методом, используя .pfx сертификаты. Однако попытка реализовать второй метод, который подразумевает использование сертификатов, установленных на машине пользователя, может столкнуться с определенными проблемами. Ключевые моменты включают:
-
Безопасность браузера: Веб-браузеры имеют жесткие ограничения на доступ к файловой системе пользователя. Это делается для повышения безопасности пользователей, и поэтому прямой доступ к установленным сертификатам невозможен.
- Java Applets: Использование Java Applet для доступа к сертификатам больше не рекомендуется и, как вы отметили, было устаревшим. Это также не является практичным решением с точки зрения безопасности.
Возможные решения
1. Использование Web Crypto API
Этот API предоставляет возможность выполнения криптографических операций прямо в браузере. Однако для работы с сертификатами вам, скорее всего, потребуется, чтобы пользователь сам предоставил вам доступ к необходимым сертификатам. Это может быть сделано через загрузку файла сертификата:
async function loadCertificate() {
const fileInput = document.getElementById('certFile');
const file = fileInput.files[0];
const arrayBuffer = await file.arrayBuffer();
const cert = await crypto.subtle.importKey('spki', arrayBuffer, { name: 'RSA-PSS', hash: 'SHA-256' }, true, ['sign']);
return cert;
}
Пользователь выбирает файл сертификата, и вы можете загрузить и использовать его для подписи.
2. Использование Electron для настольных приложений
Если ваше Angular приложение работает в режиме настольного приложения с помощью Electron, вы получаете значительно больше возможностей. Electron позволяет вашему приложению взаимодействовать с локальной файловой системой и позволяет вам получать доступ к установленным сертификатам через Node.js. Вы можете использовать такие модули, как node-forge
, для работы с сертификатами.
const fs = require('fs');
const forge = require('node-forge');
fs.readFile('path/to/certificate.crt', (err, data) => {
if (err) throw err;
const cert = forge.pki.certificateFromAsn1(forge.asn1.fromDer(data.toString('binary')));
// Используйте сертификат для подписи
});
3. Установка и настройка на стороне пользователя
Если для вашего приложения критически важно использовать уже установленные на компьютере сертификаты, вы можете рассмотреть возможность создания инструкции для пользователей, чтобы они экспортировали нужные сертификаты и загружали их через пользовательский интерфейс вашего приложения.
Заключение
К сожалению, нет простого способа автоматически получить доступ к сертификатам, установленным на компьютах пользователей, в веб-контексте. Однако использование подходов, таких как Web Crypto API в сочетании с пользовательским вводом или разработка настольного приложения с Electron, может помочь вам реализовать необходимые функции. Краснодарский инженерный подход должен учитывать безопасность и удобство пользователей, поэтому старайтесь предоставить инструкции и средства для загрузки сертификатов, но избегать прямых операций с локальной файловой системой без участия пользователя.