@mmskazak/crypto-pro-plus
v1.0.0
Published
Обёртка над cadesplugin для CryptoPro. Простая подпись, подпись с TSP, выбор сертификатов.
Maintainers
Readme
@mmskazak/crypto-pro-plus
📦 Современная обёртка над CryptoPro CAdES plugin
Позволяет удобно работать с сертификатами, получать информацию, подписывать данные (attached/detached) и добавлять метку времени — всё на async/await.
🚀 Установка
npm install @mmskazak/crypto-pro-plus⚠️ Требуется установленный CryptoPro CSP и плагин
cadesplugin.
🧠 Возможности
- 🔍 Проверка версии плагина
- 📋 Получение списка сертификатов
- 🧾 Получение информации по сертификату
- ✍️ Detached/Attached подпись (CAdES-BES)
- ⏱ Подпись с меткой времени (CAdES-T)
- 👥 Множественные подписи (коллективные, последовательные)
- 🛡️ Контрподписи (заверение подписей)
- ✅ Проверка валидности цифровых подписей (включая множественные подписи)
- 🔐 Создание хешей (SHA-1/256/384/512, ГОСТ Р 34.11-94/2012-256/2012-512)
- ✍️ Подпись хешей любых алгоритмов (detached с поддержкой меток времени)
- 🔄 Конвертация Unicode-строк в корректный base64
🏗 Модульная структура
Библиотека полностью организована по модульному принципу. Каждый модуль отвечает за свою область функциональности:
crypto-pro-plus/
├── src/
│ ├── common.js # Общие функции (pluginVersion, openCertificateStore)
│ ├── certificates.js # Работа с сертификатами
│ ├── signing.js # Подпись данных (attached/detached)
│ ├── multiple-signing.js # Множественные подписи (коллективные, последовательные)
│ ├── hashing.js # Создание хешей
│ ├── hash-signing.js # Подпись хешей
│ ├── verification.js # Проверка подписей
│ ├── countersigning.js # Контрподписи
│ └── utils.js # Утилиты (toBase64Unicode)
├── cadesplugin-wrapper.js
└── cadesplugin_api.jsИмпорт модулей
// Работа с сертификатами
import { getCertificates, getCertificateInfo } from '@mmskazak/crypto-pro-plus/certificates';
// Подпись данных
import { signBase64Detached } from '@mmskazak/crypto-pro-plus/signing';
// Создание хешей
import { createSHA256Hash, createGost2012_256Hash } from '@mmskazak/crypto-pro-plus/hashing';
// Подпись хешей
import { signSHA256HashDetached } from '@mmskazak/crypto-pro-plus/hash-signing';
// Проверка подписей
import { verifyDetachedSignature } from '@mmskazak/crypto-pro-plus/verification';
// Множественные подписи
import { coSignBase64, createCollectiveSignature, createSequentialSignature } from '@mmskazak/crypto-pro-plus/multiple-signing';
// Контрподписи
import { counterSign } from '@mmskazak/crypto-pro-plus/countersigning';
// Утилиты
import { toBase64Unicode } from '@mmskazak/crypto-pro-plus/utils';
// Общие функции
import { pluginVersion } from '@mmskazak/crypto-pro-plus/common';📘 Примеры
✅ Проверка плагина
import { pluginVersion } from '@mmskazak/crypto-pro-plus/common';
import { countCertificates } from '@mmskazak/crypto-pro-plus/certificates';
const version = await pluginVersion();
console.log("Версия плагина:", version);
const count = await countCertificates();
console.log("Сертификатов найдено:", count);📜 Получение всех сертификатов
import { getCertificates } from '@mmskazak/crypto-pro-plus/certificates';
const certs = await getCertificates();
certs.forEach(cert => {
console.log(cert.subjectName, cert.thumbprint, cert.validToDate);
});📄 Информация по сертификату
import { getCertificateByThumbprint, getCertificateInfo } from '@mmskazak/crypto-pro-plus/certificates';
const cert = await getCertificateByThumbprint("DA9142...");
const info = await getCertificateInfo(cert);
console.log(info);✍️ Detached-подпись (без метки)
import { signBase64Detached } from '@mmskazak/crypto-pro-plus/signing';
import { toBase64Unicode } from '@mmskazak/crypto-pro-plus/utils';
const data = toBase64Unicode("Данные для подписи");
const signature = await signBase64Detached(data, "DA9142...");
console.log(signature);⏱ Detached-подпись с меткой времени
import { signBase64DetachedWithTimestamp } from '@mmskazak/crypto-pro-plus/signing';
const signature = await signBase64DetachedWithTimestamp(data, "DA9142...", "http://testca.cryptopro.ru/tsp/");
console.log(signature);📎 Attached-подпись (встроенная)
import { signBase64Attached } from '@mmskazak/crypto-pro-plus/signing';
const signature = await signBase64Attached(data, "DA9142...");
console.log(signature);📎⏱ Attached-подпись с меткой времени
import { signBase64AttachedWithTimestamp } from '@mmskazak/crypto-pro-plus/signing';
const signature = await signBase64AttachedWithTimestamp(data, "DA9142...", "http://testca.cryptopro.ru/tsp/");
console.log(signature);🎯 Подпись с выбором сертификата
import { signWithCertificateSelection } from '@mmskazak/crypto-pro-plus/signing';
import { toBase64Unicode } from '@mmskazak/crypto-pro-plus/utils';
const data = toBase64Unicode("Важный документ");
// Пользователю покажется диалог выбора сертификата
const result = await signWithCertificateSelection(
data,
true, // isDetached
"http://testca.cryptopro.ru/tsp/" // опционально TSP
);
console.log('Подпись:', result.signature);
console.log('Сертификат:', result.certificateInfo.subjectName);
console.log('Предупреждения:', result.certificateInfo.warnings);🛡️ Безопасное подписание с проверкой
import { signWithValidation, validateCertificateForSigning } from '@mmskazak/crypto-pro-plus/signing';
// Сначала проверим сертификат
const validation = await validateCertificateForSigning("DA9142...");
if (!validation.isValid) {
console.error('Сертификат недействителен:', validation.reason);
return;
}
// Подписываем с проверкой
try {
const result = await signWithValidation(data, "DA9142...", true);
console.log('Подпись создана:', result.signature);
} catch (error) {
console.error('Ошибка подписания:', error.message);
}🔐 Создание хешей
import {
createGost2012_256Hash,
createSHA256Hash,
createSHA512Hash,
createHash
} from '@mmskazak/crypto-pro-plus/hashing';
import { toBase64Unicode } from '@mmskazak/crypto-pro-plus/utils';
const data = toBase64Unicode("Данные для хеширования");
// ГОСТ Р 34.11-2012 256 бит
const gost256Hash = await createGost2012_256Hash(data);
// SHA-256
const sha256Hash = await createSHA256Hash(data);
// SHA-512
const sha512Hash = await createSHA512Hash(data);
// Универсальная функция с любым алгоритмом
import { cadesplugin } from '@mmskazak/crypto-pro-plus/cadesplugin-wrapper';
const customHash = await createHash(data, cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_384);✍️ Подпись хешей (detached)
import {
signGost2012_256HashDetached,
signSHA256HashDetached,
signHashDetached
} from '@mmskazak/crypto-pro-plus/hash-signing';
// Подпись ГОСТ-хеша
const gost256Signature = await signGost2012_256HashDetached(gost256Hash, "DA9142...");
// Подпись SHA-256 хеша
const sha256Signature = await signSHA256HashDetached(sha256Hash, "DA9142...");
// Универсальная функция
import { cadesplugin } from '@mmskazak/crypto-pro-plus/cadesplugin-wrapper';
const customSignature = await signHashDetached(
customHash,
"DA9142...",
cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_384
);✍️⏱ Подпись хешей с меткой времени
import {
signGost2012_256HashDetachedWithTimestamp,
signSHA256HashDetachedWithTimestamp,
signHashDetachedWithTimestamp
} from '@mmskazak/crypto-pro-plus/hash-signing';
// ГОСТ с меткой времени
const gost256Signature = await signGost2012_256HashDetachedWithTimestamp(
gost256Hash,
"DA9142...",
"http://testca.cryptopro.ru/tsp/"
);
// SHA-256 с меткой времени
const sha256Signature = await signSHA256HashDetachedWithTimestamp(
sha256Hash,
"DA9142...",
"http://testca.cryptopro.ru/tsp/"
);
// Универсальная функция с меткой времени
import { cadesplugin } from '@mmskazak/crypto-pro-plus/cadesplugin-wrapper';
const customSignature = await signHashDetachedWithTimestamp(
customHash,
"DA9142...",
cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_384,
"http://testca.cryptopro.ru/tsp/"
);✅ Проверка подписей
import {
verifyDetachedSignature,
verifyAttachedSignature,
verifyTimestampedSignature,
getSignersInfo
} from '@mmskazak/crypto-pro-plus/verification';
// Проверка detached подписи
const isValidDetached = await verifyDetachedSignature(originalData, signature);
console.log('Detached подпись валидна:', isValidDetached);
// Проверка attached подписи
const attachedResult = await verifyAttachedSignature(signedMessage);
console.log('Attached подпись валидна:', attachedResult.isValid);
if (attachedResult.isValid) {
console.log('Извлеченные данные:', attachedResult.content);
}
// Проверка подписи с меткой времени
const timestampResult = await verifyTimestampedSignature(originalData, signature, true);
console.log('Подпись с меткой времени валидна:', timestampResult.isValid);
if (timestampResult.timestampInfo) {
console.log('Время подписи:', timestampResult.timestampInfo.signingTime);
}
// Получение информации о всех подписчиках (может быть несколько!)
const signersInfo = await getSignersInfo(signature, true, originalData);
console.log(`Найдено подписчиков: ${signersInfo.length}`);
signersInfo.forEach((signer, index) => {
console.log(`\n--- Подписчик ${index + 1} ---`);
console.log('Имя:', signer.subjectName);
console.log('Издатель сертификата:', signer.issuerName);
console.log('Отпечаток сертификата:', signer.thumbprint);
console.log('Время подписи:', signer.signingTime);
console.log('Сертификат действителен с:', signer.validFromDate);
console.log('Сертификат действителен до:', signer.validToDate);
});👥 Множественные подписи
import {
coSignBase64,
coSignBase64WithTimestamp,
createMultipleSignature,
createSequentialSignature
} from '@mmskazak/crypto-pro-plus/multiple-signing';
// Добавление соподписи к существующей подписи
const coSignedData = await coSignBase64(
originalData,
existingSignature,
secondSignerThumbprint,
true // isDetached
);
// Создание коллективной подписи сразу несколькими подписчиками
const thumbprints = ["cert1_thumbprint", "cert2_thumbprint", "cert3_thumbprint"];
// Коллективная подпись (все подписывают исходные данные одновременно)
const collectiveSignature = await createCollectiveSignature(
originalData,
thumbprints,
true, // isDetached
"http://testca.cryptopro.ru/tsp/" // опционально TSP для всех
);
// Последовательная подпись (цепочка: каждый подписывает результат предыдущего)
const signers = [
{ thumbprint: "manager_cert", tspUrl: "http://testca.cryptopro.ru/tsp/" },
{ thumbprint: "director_cert", tspUrl: "http://testca.cryptopro.ru/tsp/" },
{ thumbprint: "accountant_cert" } // без TSP
];
const sequentialResult = await createSequentialSignature(originalData, signers, true);
console.log('Финальная подпись:', sequentialResult.signature);
console.log('История подписания:', sequentialResult.history);🛡️ Контрподписи (заверение подписей)
import {
counterSign,
counterSignBySigner,
counterSignAll,
getCounterSignersInfo
} from '@mmskazak/crypto-pro-plus/countersigning';
// Создание контрподписи (заверение первого подписчика)
const counterSignedData = await counterSign(
existingSignature,
notaryThumbprint,
"http://testca.cryptopro.ru/tsp/" // опционально
);
// Контрподпись конкретного подписчика (по индексу)
const counterSignedSpecific = await counterSignBySigner(
existingSignature,
notaryThumbprint,
2, // индекс подписчика
"http://testca.cryptopro.ru/tsp/"
);
// Контрподпись всех подписчиков
const counterSignedAll = await counterSignAll(
existingSignature,
notaryThumbprint,
"http://testca.cryptopro.ru/tsp/"
);
// Получение информации о контрподписях
const counterSignersInfo = await getCounterSignersInfo(signature, originalData, true);
counterSignersInfo.forEach(info => {
console.log(`Подписчик: ${info.signerName}`);
info.counterSignatures.forEach(cs => {
console.log(` Заверил: ${cs.counterSignerName} в ${cs.counterSigningTime}`);
});
});🔐 Поддерживаемые алгоритмы хеширования
| Алгоритм | Константа | Функции |
|----------|-----------|---------|
| SHA-1 | CADESCOM_HASH_ALGORITHM_SHA1 | createSHA1Hash, signSHA1HashDetached* |
| SHA-256 | CADESCOM_HASH_ALGORITHM_SHA_256 | createSHA256Hash, signSHA256HashDetached* |
| SHA-384 | CADESCOM_HASH_ALGORITHM_SHA_384 | createSHA384Hash, signSHA384HashDetached* |
| SHA-512 | CADESCOM_HASH_ALGORITHM_SHA_512 | createSHA512Hash, signSHA512HashDetached* |
| ГОСТ Р 34.11-94 | CADESCOM_HASH_ALGORITHM_CP_GOST_3411 | createGost94Hash, signGost94HashDetached* |
| ГОСТ Р 34.11-2012 256 | CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256 | createGost2012_256Hash, signGost2012_256HashDetached* |
| ГОСТ Р 34.11-2012 512 | CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_512 | createGost2012_512Hash, signGost2012_512HashDetached* |
Примечание:
*означает, что доступны варианты как без метки времени, так и с меткой времени (WithTimestamp)
📌 API
| Метод | Описание | | ---------------------------------------------------------------- | -------------------------------------------------------------------------- | | pluginVersion() | Возвращает версию установленного плагина | | countCertificates() | Считает количество сертификатов в личном хранилище | | getCertificates() | Получает список сертификатов с SubjectName, Thumbprint, сроками и объектом | | getCertificateByThumbprint(thumbprint) | Возвращает объект сертификата по отпечатку | | getCertificateInfo(cert) | Возвращает подробную информацию о сертификате | | selectCertificateFromDialog(title) | Показывает диалог выбора сертификата пользователю | | getValidCertificates() | Получает список всех действующих сертификатов | | validateCertificateForSigning(thumbprint) | Проверяет может ли сертификат использоваться для подписания | | signBase64Detached(dataBase64, thumbprint) | Detached-подпись без метки времени (CAdES-BES) | | signBase64DetachedWithTimestamp(dataBase64, thumbprint, tspUrl) | Detached-подпись с меткой времени (CAdES-T) | | signBase64Attached(dataBase64, thumbprint) | Attached-подпись без метки времени (CAdES-BES) | | signBase64AttachedWithTimestamp(dataBase64, thumbprint, tspUrl) | Attached-подпись с меткой времени (CAdES-T) | | signWithCertificateSelection(dataBase64, isDetached, tspUrl) | Подпись с выбором сертификата через диалог | | signWithValidation(dataBase64, thumbprint, isDetached, tspUrl) | Безопасное подписание с проверкой сертификата | | Функции хеширования | | | createHash(dataBase64, algorithm) | Универсальная функция создания хеша с любым алгоритмом | | createGost2012_256Hash(dataBase64) | Создает ГОСТ-хеш данных (ГОСТ Р 34.11-2012 256 бит) | | createSHA1Hash(dataBase64) | Создает SHA-1 хеш данных | | createSHA256Hash(dataBase64) | Создает SHA-256 хеш данных | | createSHA384Hash(dataBase64) | Создает SHA-384 хеш данных | | createSHA512Hash(dataBase64) | Создает SHA-512 хеш данных | | createGost2012_512Hash(dataBase64) | Создает ГОСТ Р 34.11-2012 512 бит хеш данных | | createGost94Hash(dataBase64) | Создает ГОСТ Р 34.11-94 хеш данных | | Функции подписи хешей | | | signHashDetached(hashBase64, thumbprint, algorithm) | Универсальная detached-подпись хеша без метки времени | | signHashDetachedWithTimestamp(hashBase64, thumbprint, algorithm, tspUrl) | Универсальная detached-подпись хеша с меткой времени | | signGost2012_256HashDetached(hashBase64, thumbprint) | Detached-подпись ГОСТ 2012-256 хеша без метки времени (CAdES-BES) | | signGost2012_256HashDetachedWithTimestamp(hashBase64, thumbprint, tspUrl)| Detached-подпись ГОСТ 2012-256 хеша с меткой времени (CAdES-T) | | signSHA1HashDetached(hashBase64, thumbprint) | Detached-подпись SHA-1 хеша без метки времени | | signSHA1HashDetachedWithTimestamp(hashBase64, thumbprint, tspUrl)| Detached-подпись SHA-1 хеша с меткой времени | | signSHA256HashDetached(hashBase64, thumbprint) | Detached-подпись SHA-256 хеша без метки времени | | signSHA256HashDetachedWithTimestamp(hashBase64, thumbprint, tspUrl)| Detached-подпись SHA-256 хеша с меткой времени | | signSHA384HashDetached(hashBase64, thumbprint) | Detached-подпись SHA-384 хеша без метки времени | | signSHA384HashDetachedWithTimestamp(hashBase64, thumbprint, tspUrl)| Detached-подпись SHA-384 хеша с меткой времени | | signSHA512HashDetached(hashBase64, thumbprint) | Detached-подпись SHA-512 хеша без метки времени | | signSHA512HashDetachedWithTimestamp(hashBase64, thumbprint, tspUrl)| Detached-подпись SHA-512 хеша с меткой времени | | signGost2012_512HashDetached(hashBase64, thumbprint) | Detached-подпись ГОСТ 2012-512 хеша без метки времени | | signGost2012_512HashDetachedWithTimestamp(hashBase64, thumbprint, tspUrl)| Detached-подпись ГОСТ 2012-512 хеша с меткой времени | | signGost94HashDetached(hashBase64, thumbprint) | Detached-подпись ГОСТ-94 хеша без метки времени | | signGost94HashDetachedWithTimestamp(hashBase64, thumbprint, tspUrl)| Detached-подпись ГОСТ-94 хеша с меткой времени | | Функции множественных подписей | | | coSignBase64(dataBase64, existingSignature, thumbprint, isDetached) | Добавляет соподпись к существующей подписи | | coSignBase64WithTimestamp(dataBase64, existingSignature, thumbprint, tspUrl, isDetached) | Добавляет соподпись с меткой времени | | createCollectiveSignature(dataBase64, thumbprints, isDetached, tspUrl) | Создает коллективную подпись (все подписывают исходные данные) | | createSequentialSignature(dataBase64, signers, isDetached) | Создает последовательную подпись (цепочка подписей) | | createMultipleSignature(dataBase64, thumbprints, isDetached, tspUrl) | Алиас для createCollectiveSignature (обратная совместимость) | | Функции проверки подписей | | | verifyDetachedSignature(dataBase64, signatureBase64, checkCert) | Проверяет detached подпись CAdES | | verifyAttachedSignature(signatureBase64, checkCert) | Проверяет attached подпись CAdES | | verifyTimestampedSignature(dataBase64, signatureBase64, isDetached)| Проверяет подпись с меткой времени CAdES-T | | getSignersInfo(signatureBase64, isDetached, dataBase64) | Получает информацию о всех подписчиках (поддержка множественных подписей) | | verifySignature(signatureBase64, options) | Универсальная функция проверки подписи | | Функции контрподписей | | | counterSign(existingSignature, thumbprint, tspUrl) | Создает контрподпись (заверение подписи) | | counterSignBySigner(existingSignature, thumbprint, signerIndex, tspUrl) | Контрподпись конкретного подписчика | | counterSignAll(existingSignature, thumbprint, tspUrl) | Контрподпись всех подписчиков | | getCounterSignersInfo(signatureBase64, dataBase64, isDetached) | Получает информацию о контрподписях | | Утилиты | | | toBase64Unicode(str) | Кодирует строку в корректный base64 с поддержкой Unicode |
🧑💻 Автор
Михаил Мельников — github.com/mmskazak
📜 Лицензия
MIT
