@napopravku/eds-cryptopro
v0.1.1
Published
Библиотека для работы с электронной подписью КриптоПро в браузере
Readme
@napopravku/eds-cryptopro
Библиотека для работы с электронной подписью КриптоПро в браузере.
📦 Установка
npm install @napopravku/eds-cryptoproили
yarn add @napopravku/eds-cryptopro🚀 Быстрый старт
Библиотека работает "из коробки" - дополнительная настройка не требуется!
Простое использование
import { CryptoProService } from '@napopravku/eds-cryptopro';
async function init() {
try {
// Плагин загрузится автоматически!
await CryptoProService.initialize();
console.log('Плагин КриптоПро успешно инициализирован');
// Получаем список сертификатов
const certificates = await CryptoProService.getCertificates();
console.log('Найдено сертификатов:', certificates.length);
} catch (error) {
console.error('Ошибка:', error);
}
}
init();📖 Процесс работы библиотеки
Инициализация
Пользователь вызывает
initialize()- Библиотека проверяет, загружен ли уже плагин КриптоПро
- Если нет, начинает автоматический поиск файла
cadesplugin_api.js
Автоматическая загрузка плагина
- Библиотека последовательно проверяет несколько стандартных путей:
/node_modules/@napopravku/eds-cryptopro/lib/cadesplugin_api.js/cadesplugin_api.js/assets/cadesplugin_api.js/js/cadesplugin_api.js/lib/cadesplugin_api.js
- Как только файл найден, он загружается динамически
- Библиотека последовательно проверяет несколько стандартных путей:
Подключение к браузерному расширению
- Загруженный плагин ищет установленное браузерное расширение КриптоПро
- Устанавливается связь между JavaScript и расширением
- Библиотека готова к работе
Получение сертификатов
- Вызов
getCertificates()- Открывается хранилище сертификатов операционной системы
- Извлекаются все доступные сертификаты
- Фильтруются только сертификаты с закрытым ключом (пригодные для подписи)
- Формируется читаемое имя для каждого сертификата
- Возвращается массив с информацией о сертификатах
Создание подписи
Подготовка данных для подписи
- Исходные данные (строка или объект) → конвертируются в строку
- Строка кодируется в Base64 (для корректной передачи в плагин)
Вызов
signData(данные, индекс_сертификата)- Выбирается нужный сертификат по индексу
- Создается объект подписи CAdES-BES (стандарт электронной подписи)
- Данные подписываются с использованием закрытого ключа сертификата
- Возвращается подпись в формате Base64
Типы подписи
- Отделенная подпись (по умолчанию): подпись отдельно, данные отдельно
- Присоединенная подпись: подпись содержит в себе данные
Проверка подписи
- Вызов
verifySignature(данные, подпись)- Исходные данные кодируются в Base64 (если еще не закодированы)
- Подпись проверяется на валидность
- Проверяется соответствие подписи данным
- Проверяется срок действия сертификата
- Проверяется цепочка доверия сертификата
- Возвращается результат:
{ isValid: true }или{ isValid: false, error: "описание" }
Формат данных
Для подписания строк:
const signature = await CryptoProService.signData('Текст документа', 0);Для подписания файлов (например, XML):
// 1. Читаем файл
const fileContent = await readFile('document.xml');
// 2. Конвертируем в Base64
const base64Content = btoa(fileContent);
// 3. Подписываем
const signature = await CryptoProService.signData(base64Content, 0);
// При проверке указываем, что данные уже в Base64:
const result = await CryptoProService.verifySignature(
base64Content,
signature,
true // isDataBase64 = true
);Очистка ресурсов
- Вызов
clearCertificates()(опционально)- Очищает кэш загруженных сертификатов
- Используется при необходимости обновить список сертификатов
📖 Документация API
Методы
initialize(): Promise<void>
Инициализирует плагин КриптоПро. Должен быть вызван перед использованием других методов.
await CryptoProService.initialize();getCertificates(): Promise<ICertificateInfo[]>
Получает список сертификатов с закрытым ключом.
const certificates = await CryptoProService.getCertificates();
console.log('Доступные сертификаты:', certificates);Возвращает: массив объектов типа ICertificateInfo:
interface ICertificateInfo {
id: number; // Индекс сертификата
name: string; // Имя сертификата
validFrom: Date; // Дата выдачи
cert: any; // Объект сертификата
}signData(dataToSign: string, certIndex: number, isDetached?: boolean): Promise<string>
Создает отделенную подпись CAdES-BES.
Параметры:
dataToSign- данные для подписи (строка)certIndex- индекс сертификата из списка (полеidизICertificateInfo)isDetached- создать отделенную подпись (по умолчаниюtrue)
Возвращает: подпись в формате base64
const signature = await CryptoProService.signData('Данные для подписи', 0);
console.log('Подпись:', signature);verifySignature(originalData: string, signature: string, isDataBase64?: boolean): Promise<IVerifyResult>
Проверяет отделенную подпись CAdES.
Параметры:
originalData- исходные данныеsignature- подпись в формате base64isDataBase64- еслиtrue, то originalData уже в base64 (по умолчаниюfalse)
Возвращает: объект типа IVerifyResult:
interface IVerifyResult {
isValid: boolean; // Подпись валидна
error?: string; // Описание ошибки (если подпись невалидна)
}const result = await CryptoProService.verifySignature(
'Исходные данные',
signatureString
);
if (result.isValid) {
console.log('Подпись валидна');
} else {
console.error('Подпись невалидна:', result.error);
}clearCertificates(): void
Очищает кэш сертификатов.
CryptoProService.clearCertificates();💡 Примеры использования
Полный пример подписи документа
import { CryptoProService, ICertificateInfo } from '@napopravku/eds-cryptopro';
async function signDocument() {
try {
// 1. Инициализация плагина
await CryptoProService.initialize();
// 2. Получение списка сертификатов
const certificates = await CryptoProService.getCertificates();
if (certificates.length === 0) {
throw new Error('Сертификаты не найдены');
}
// 3. Выбор первого сертификата
const selectedCert = certificates[0];
console.log('Используется сертификат:', selectedCert.name);
// 4. Данные для подписи
const dataToSign = 'Важный документ для подписи';
// 5. Создание подписи
const signature = await CryptoProService.signData(
dataToSign,
selectedCert.id
);
console.log('Подпись успешно создана:', signature);
// 6. Проверка подписи
const verifyResult = await CryptoProService.verifySignature(
dataToSign,
signature
);
if (verifyResult.isValid) {
console.log('Подпись валидна!');
} else {
console.error('Ошибка проверки:', verifyResult.error);
}
} catch (error) {
console.error('Ошибка:', error);
}
}
signDocument();Использование с Vue 3 (Composition API)
<template>
<div>
<div v-if="!isInitialized">
Загрузка плагина КриптоПро...
</div>
<div v-else>
<h2>Доступные сертификаты:</h2>
<div v-if="error" class="error">
{{ error }}
</div>
<ul v-if="certificates.length > 0">
<li v-for="cert in certificates" :key="cert.id">
{{ cert.name }}
<button @click="handleSign(cert.id)">Подписать</button>
</li>
</ul>
<p v-else>
Сертификаты не найдены
</p>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { CryptoProService, type ICertificateInfo } from '@napopravku/eds-cryptopro';
const certificates = ref<ICertificateInfo[]>([]);
const isInitialized = ref(false);
const error = ref<string | null>(null);
onMounted(async () => {
try {
// Инициализация плагина (загрузится автоматически)
await CryptoProService.initialize();
isInitialized.value = true;
// Получение списка сертификатов
const certs = await CryptoProService.getCertificates();
certificates.value = certs;
} catch (err) {
console.error('Ошибка инициализации:', err);
error.value = err instanceof Error ? err.message : 'Неизвестная ошибка';
}
});
const handleSign = async (certId: number) => {
try {
const signature = await CryptoProService.signData(
'Данные для подписи',
certId
);
console.log('Подпись создана:', signature);
alert('Подпись успешно создана!');
} catch (err) {
console.error('Ошибка подписи:', err);
error.value = err instanceof Error ? err.message : 'Ошибка подписи';
}
};
</script>
<style scoped>
.error {
color: red;
padding: 10px;
background-color: #fee;
border-radius: 4px;
margin: 10px 0;
}
</style>🔧 Требования
- Браузер: Chrome, Firefox, Safari, Edge (современные версии)
- Плагин: КриптоПро ЭЦП Browser plug-in (должен быть установлен в системе)
- Node.js: >= 14.0.0 (для сборки проекта)
📝 TypeScript
Библиотека полностью написана на TypeScript и включает типы из коробки. Никаких дополнительных установок @types не требуется.
⚠️ Важные примечания
- Плагин КриптоПро должен быть установлен в системе пользователя (браузерное расширение)
- Файл плагина загружается автоматически - никаких дополнительных действий не требуется
- Библиотека автоматически ищет плагин в нескольких стандартных местах
- Методы работают асинхронно - используйте
async/awaitили промисы - Для работы с сертификатами требуется закрытый ключ
- Библиотека работает только в браузере, не поддерживается в Node.js окружении
Если плагин не загружается
В редких случаях может потребоваться вручную скопировать файл cadesplugin_api.js:
# Скопируйте в public директорию вашего проекта
cp node_modules/@napopravku/eds-cryptopro/lib/cadesplugin_api.js public/Как это работает?
При вызове initialize() библиотека автоматически попытается загрузить плагин КриптоПро из нескольких стандартных мест:
/node_modules/@napopravku/eds-cryptopro/lib/cadesplugin_api.js/cadesplugin_api.js/assets/cadesplugin_api.js/js/cadesplugin_api.js/lib/cadesplugin_api.js
Если вы хотите указать собственный путь к плагину:
// Укажите явный путь
await CryptoProService.initialize('/custom/path/cadesplugin_api.js'); 📄 Лицензия
MIT © Napopravku
