@it-enterprise/digital-signature

1.2.12 • Public • Published

Настройка веб-сервера

Для работы пакет требует наличие специального api на веб-сервере.
Для добавления этого api необходимо установить nuget пакет ItEnterprise.DigitalSignature.Web

Install-Package ItEnterprise.DigitalSignature.Web

Подключение

using ItEnterprise.DigitalSignature.Web;
using ItEnterprise.DigitalSignature.Models;

namespace TestApp.Web.NetCore
{
  public class Startup
  {
    public void ConfigureServices(IServiceCollection services)
    {
      services.AddDigitalSignature(builder => builder
        .AddCertiticateUpdatesService(
          // Ссылка на веб-сервисы. Необходимо для обновления коревых сертификатов и списка ЦСК
          "https://m.it.ua/ws",
          // Получать значение параметра GlSign через веб-расчёт
          false
        ).SetConfig(new DigitalSignatureConfiguration
        {
          // Использовать нативные библиотеки. true, если будет использоваться C# API ЕЦП. Нативные библиотеки необходимо устанавливать отдельными nuget пакетами
          UseNativeLibraries = false,
          GlSign = new GlSignInfo { 
            // Разрешать использовать тестовые ключи
            AllowTestKeys = true 
          }
        }));
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      // Путь, по которому будет доступно API ЕЦП
      app.UseDigitalSignature("/api/ds");
    }
  }
}

Установка

@it-enterprise/digital-signature

npm install @it-enterprise/digital-signature

Импорт

import {
  DigitalSignature,
  GlSign,
  Models,
  Utils,
  EUSignCP
} from "@it-enterprise/digital-signature";

Инициализация

Инициализация библиотеки

import {
  DigitalSignature,
  Models
} from "@it-enterprise/digital-signature";

const ds = new DigitalSignature(
  new Models.DefaultSettingProvider(
    "uk", // Язык ошибок (строка, или функция, возвращающая строку)
    userId, // id пользователя (для сохранения ключей и предпочитаемого типа ключа) (строка, или функция, возвращающая строку)
    location.pathname + "api/ds/") // Путь к API ЕЦП
  );
// Возвращает текущий тип ключа (файловый, аппаратный, облачный)
const currentKeyType = await ds.initialise();

Сменить тип библиотеки

/** Подпись файловыми ключами, через облачные сервисы  */
const DigitalSignatureLibraryTypeJS = 0;
/** Подпись аппартными ключами */
const DigitalSignatureLibraryTypeSW = 1;
/**
 * Типы библиотеки
 */
enum DigitalSignatureLibraryType = {
  /** Подпись файловыми ключами и через облачные сервисы */
  JS: DigitalSignatureLibraryTypeJS,
  /** Подпись аппартными ключами */
  SW: DigitalSignatureLibraryTypeSW
};

import { Models } from "@it-enterprise/digital-signature";

await ds.setLibraryType(Models.DigitalSignatureLibraryType.JS);

Центры сертификации ключей

Получение списка сертификации ключей

const cas = await ds.getCAs();

Установить центр сертификации ключей

// Предоставить возможность пользователю выбирать ЦСК. Для автоматического определения ЦСК установить значение null
const ca = cas[0];
await ds.setCA(ca);

Проверить, поддерживает ли ЦСК автоматическую загрузку сертификатов
Если ЦСК не поддерживает автоматическую загрузку сертификатов, нужно предоставить возможность пользователю вручную указать сертификаты

const needCerts = ds.needPrivateKeyCertificates();

Структура объекта CASettings

import { EUSignCP.CASettings } from "@it-enterprise/digital-signature";

class CASettings {
    // Названия ЦСК (обычно используется первое из списка)
    issuerCNs: Array<string>;
    address: string;
    ocspAccessPointAddress: string;
    ocspAccessPointPort: string;
    cmpAddress: string;
    tspAddress: string;
    tspAddressPort: string;
    directAccess: boolean;
    certsInKey: boolean;
    cmpCompatibility: number;
    qscdSNInCert: boolean;
}

Файловые ключи

Обычные файловые ключи

Считывание

const ownerInfo = await ds.readFileKey(
  // Файл с ключом
  privateKey,
  // Пароль
  password,
  // Сертификаты ключа (необязательно)
  privateKeyCertificates
);

JKS-контейнеры

Проверка, является ли файл JKS-контейнером

const isJKSContainer = ds.isJKSContainer(/* Файл с ключом */ fileKey);

Получение списка ключей из JKS-контейнера

const JKSPrivateKeys = await ds.getJKSPrivateKeys(/* Файл с ключом */ fileKey);

Считывание одного из ключей

// Предоставить пользователю возможность выбрать ключ из списка, полученного из метода getJKSPrivateKeys
const JKSPrivateKey = JKSPrivateKeys[0];

const keyInfo = await ds.readFileKey(
  JKSPrivateKey.privateKey,
  password,
  JKSPrivateKey.certificates.select(cert => cert.data)
);

Аппаратные ключи

Получение списка ключей

const keyMedias = await ds.getKeyMedias();

Считывание ключа

// Предоставить пользователю возможность выбрать ключ из списка, полученного из метода getKeyMedias
const hardwareKey = keyMedias[0];

hardwareKey.password = password;

const keyInfo = await ds.readHardwareKey(
  // Информация о ключе
  hardwareKey,
  // Сертификаты ключа (необязательно)
  privateKeyCertificates
);

Облачные ключи

Провайдеры облачныч ключей есть 2х видов: работающие через QR код (Дія.Підпис, SmartID, CloudKey) и через ID пользователя (DepositSign, ESign, Вчасно)
Получение списока провайдеров облачных ключей

const ksps = ds.KSPs;

Содержимое обьекта KSP

class KSPSettings {
    // Идентификатор
    id: string;
    // Название провайдера
    name: string;
    // Провайдер работает через QR код или через ID пользователя
    needQRCode: boolean;
    // Тип ID пользователя (имя пользователя/телефон/email)
    clientIdType?: EndUserKSPClientIdType;
    // Тип провайдера
    ksp: EndUserKSP;
    address?: string;
    port?: string;
    directAccess?: boolean;
    clientIdPrefix?: string;
    confirmationURL?: string;
    mobileAppName?: string;
    pollingInterval?: number;
    systemId?: string;
}
import { EUSignCP.KSPSettings } from "@it-enterprise/digital-signature";

// Тип провайдера облачных ключей
enum EndUserKSP = {
  // DepositSign, ESign, Вчасно
  IIT
  // SmartID, CloudKey
  PB
  // Дія.Підпис
  DIIA
  // Подписание ключами с Гряды через сервис подписи
  GRYADA
}
import { Models.EndUserKSP } from "@it-enterprise/digital-signature";

// Тип ID пользователя
enum EndUserKSPClientIdType = {
  // По умолчанию
  Default,
  // Имя пользователя
  Name,
  // Номер телефона
  Phone,
  // Email
  Email,
  // Имя пользователя и пароль (2 поля)
  NamePassword
}
import { Models.EndUserKSPClientIdType } from "@it-enterprise/digital-signature";

Для ключей, работающих через QR код, после инициализации библиотеки нужно подписаться на событие подтверждения операции

ds.addConfirmKSPOperationEventListener(eventArgs => { ... });

Событие будет вызываться при:

  1. Считывании ключа с getCerts = true
  2. Подписании данных

Важно! При необходимости подписать несколько файлов, нужно передавать их в функцию подписания все за раз в массиве. Иначе пользователю придётся подтверждать подписание каждого файла отдельно

Структура объекта, приходящего в коллбек события

// Аргументы события
class EndUserConfirmKSPOperationEvent {
    // Ссылка на подтверждение операции
    url: string;
    // QR код в формате data:image/bmp для подстановки в <img scr='...' />
    qrCode: string;
    // Название мобильного приложения, в котором нужно подтвердить выполнение операции
    mobileAppName: string;
    // Время, до которого действует ссылка
    expireDate: Date;
}
import { EUSignCP.EndUserEvents.EndUserConfirmKSPOperationEvent } from "@it-enterprise/digital-signature";

QR код нужно отобразить пользовтелю, что бы он мог отсканировать его в приложении и подтвердить подписание
Для отображения QR кода можно использовать содержимое поля qrCode, либо сгенерировать его на основе ссылки из поля url
Для мобильных устройств должна быть возможность переходя по ссылке из поля url, для возможности сразу запустить соответствующее приложение

Считывание ключа

// Предоставить пользователю возможность выбрать провайдера ключей
const ksp = ds.KSPs[0];

const keyInfo = await ds.readPrivateKeyKSP(
  // Объект KSP из списка ds.KSPs
  ksp
  // Идентификатор пользователя - для провайдеров ключей, работающих через ID пользователя
  // Для провайдеров ключей, работающих через QR код - null
  userID,
  // Получать информацию о сертификатах пользователя
  // true - поля ownerInfo и certificates в keyInfo будут заполены, но пользователю нужно будет подтвердить дополнительную операцию подписания
  // false - поля ownerInfo и certificates в keyInfo будут пустыми, но пользователь не получит дополнительный запрос на подписание
  getCerts = false,
  // Пароль пользователя, если clientIdType == NamePassword
  keyID = null);

Сохранение ключей

Сохранить ключ

await ds.storePrivateKeyInfo(
  // Информация о ключе
  privateKeyInfo,
  // Будет ли ключ сохранён после закрытия вкладки
  toLocalStorage,

Считать сохранённые ключи

const keyInfo = await ds.getStoredPrivateKeyInfo(
  // Тип ключа (необязательно) 
  keyType

Удалить сохранённые ключи

await ds.removeStoredPrivateKeyInfo(
  // Идентификатор ключа (необязательно)
  keyId

Создание подписей

Формат подписи

Функции создания подписей поддерживают возможность выбирать формат контейнера подписи
Формат подписи указывается в опциональном параметре signFormat
По умолчанию используется формат подписи CAdES Detached

Структура объекта, описывающего формат подписи

class EndUserSignContainerInfo {
    // Тип контейнера подписи
    type: EndUserSignContainerType;
    // Уточняющий тип подписи
    subType: EndUserCAdESType | EndUserXAdESType | EndUserASiCType;
    // Тип подписи в ASiC контейнере (только для ASiC контейнеров)
    asicSignType: EndUserASiCSignType;
}
import { EUSignCP.EndUserSignContainerInfo } from "@it-enterprise/digital-signature";

Типы контейнеров подписи

const EU_SIGN_CONTAINER_TYPE_CADES = 1;
const EU_SIGN_CONTAINER_TYPE_XADES = 2;
const EU_SIGN_CONTAINER_TYPE_PADES = 3;
const EU_SIGN_CONTAINER_TYPE_ASIC = 4;
enum EndUserSignContainerType {
    // CMS подпись в двоичном формате. Используется по умолчанию
    CAdES,
    // Подпись в формате XML. Может содержать одновременно несколько наборов данных
    XAdES,
    // Подпись в PDF документе (Работает только с PDF файлами)
    PAdES,
    // Контейнер для подписей в виде ZIP-архива
    ASiC
}
import { EUSignCP.EndUserConstants.EndUserSignContainerType } from "@it-enterprise/digital-signature";

Типы подписей CAdES

const EU_CADES_TYPE_DETACHED = 1;
const EU_CADES_TYPE_ENVELOPED = 3;
enum EndUserCAdESType {
    // Подпись отдельно от данных (внешняя подпись). Используется по умолчанию
    Detached,
    // Подпись в одном контейнере с данными (внутренняя подпись)
    Enveloped
}
import { EUSignCP.EndUserConstants.EndUserCAdESType } from "@it-enterprise/digital-signature";

Типы подписей XAdES

const EU_XADES_TYPE_DETACHED = 1;
const EU_XADES_TYPE_ENVELOPED = 3;
enum EndUserXAdESType {
    // Подпись отдельно от данных (внешняя подпись)
    Detached,
    // Подпись в одном контейнере с данными (внутренняя подпись) !! Данные могут быть только в формате XML !!
    Enveloped
}
import { EUSignCP.EndUserConstants.EndUserXAdESType } from "@it-enterprise/digital-signature";

Типы контейнеров ASiC

const EU_ASIC_TYPE_S = 1;
const EU_ASIC_TYPE_E = 2;
enum EndUserASiCType {
    // Простой контейнер, содержащий 1 файл с данными и 1 подпись
    S,
    // Расширенный контейнер, может содержать несколько файлов с данными и несколько подписей
    E
}
import { EUSignCP.EndUserConstants.EndUserASiCType } from "@it-enterprise/digital-signature";

Типы подписей, которые могут содержаться в ASiC контейнере

const EU_ASIC_SIGN_TYPE_CADES = 1;
const EU_ASIC_SIGN_TYPE_XADES = 2;
enum EndUserASiCSignType {
    CAdES,
    XAdES
}
import { EUSignCP.EndUserConstants.EndUserASiCSignType } from "@it-enterprise/digital-signature";

Пример использования формата подписи:

const file = {
  name: "file.pdf",
  val: "ссылка на загрузку файла"
};
// Формат ASiC-S с подписью XAdES
const asicsformat = {
  type: EndUserSignContainerType.ASiC,
  subType: EndUserASiCType.S,
  asicSignType: EndUserASiCSignType.XAdES
};
// Формат PAdES
const padesformat = {
  type: EndUserSignContainerType.PAdES,
};
// Внутренняя CAdES подпись
const cadesformat {
  type: EndUserSignContainerType.CAdES,
  subType: EndUserCAdESType.Enveloped
};

const asics = await ds.signFile(file, asicsformat);
const pades = await ds.signFile(file, padesformat);
const cades = await ds.signFile(file, cadesformat);

const signatures = await ds.signFile(files);

Формат передачи данных

Все функции создания подписей поддерживают следующие форматы передачи данных:

  1. Одиночный набор данных (в зависимости от функции - ссылка на загрузку файла, данные в base64 или Uint8Array и т.д.)
  2. Данные в массиве (данные как в п.1, только в массиве). Подписи так же будут возвращены в массиве
  3. Именованные данные (данные в объекте NamedData, содержащем имя набора данных и сами данные). Подпись так же будет возвращена в объекте NamedData
  4. Именованные данные в массиве (данные как в п.3, только в массиве). Результатом выполения функций будет являться массив обьектов NamedData с подписями
    Для лучшей поддержки всех форматов подписей и типов ключей, рекомендуется использовать формат из п.4

Структура объекта NamedData

declare type NamedData = {
    // Имя набора данных
    name: string;
    // В качестве параметра при создании подписи: в зависимости от функции - ссылка на загрузку файла, данные в base64 или Uint8Array и т.д.
    // В качестве возвращаемого результата: контейнер с подписью
    val: string | Uint8Array;
};
import { EUSignCP.NamedData } from "@it-enterprise/digital-signature";

Пример использования формата именованных данных

const files = [{
  name: "file1.docx",
  val: "ссылка на загрузку первого файла"
}, {
  name: "file2.pdf",
  val: "ссылка на загрузку второго файла"
}];

const signatures = await ds.signFile(files);
console.log(signatures);
// Результат
[{
  name: "file1.docx",
  val: "подпись первого файла"
}, {
  name: "file2.pdf",
  val: "подпись второго файла"
}]

Функции для создания подписей

Подписание данных

const sign = await ds.signData(
  // Данные в виде Uint8Array или строки base64
  data,
  // Формат подписи
  signFormat,
  // true - вернуть результат в виде массива байт,false - в виде строки base64. по умолчанию false
  false);

Подписание файла

const sign = await ds.signFile(
  // Ссылка на загрузку файла (например, с веб-сервисов)
  data,
  // Формат подписи. [Формат подписи]
  signFormat,
  // true - вернуть результат в виде массива байт,false - в виде строки base64. по умолчанию false
  false);

Подписание хеша в формате CAdES Detached

const sign = await ds.signHash(
  // Хеш в виде Uint8Array или строки base64
  hash,
  // true - вернуть результат в виде массива байт,false - в виде строки base64. по умолчанию false
  false);

Подписание хеша из файла в формате CAdES Detached

const sign = await ds.signFileHash(
  // Ссылка на загрузку файла с хешем
  data,
  // true - вернуть результат в виде массива байт,false - в виде строки base64. по умолчанию false
  false);

Подписание данных с получением информации о подписи

const sign = await ds.signDataEx(
  // Данные в виде Uint8Array или строки base64
  data,
  // Формат подписи
  signFormat);

Подписание файла с получением информации о подписи

const sign = await ds.signFileEx(
  // Ссылка на загрузку файла (например, с веб-сервисов)
  data,
  // Формат подписи
  signFormat);

Подписание хеша в формате CAdES Detached с получением информации о подписи

const sign = await ds.signHashEx(
  // Хеш в виде Uint8Array или строки base64
  data);

Dependencies (0)

    Dev Dependencies (2)

    Package Sidebar

    Install

    npm i @it-enterprise/digital-signature

    Weekly Downloads

    28

    Version

    1.2.12

    License

    ISC

    Unpacked Size

    488 kB

    Total Files

    31

    Last publish

    Collaborators

    • dev2it
    • bakharev
    • tokarchuk_it_enterprise
    • aleksandr.shevchenko
    • greatchief