npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@mmskazak/crypto-pro-plus

v1.0.0

Published

Обёртка над cadesplugin для CryptoPro. Простая подпись, подпись с TSP, выбор сертификатов.

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