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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@it-enterprise/digital-signature

v1.3.3

Published

digital signature

Downloads

279

Readme

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

Для работы пакет требует наличие специального 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

Важно! Пакет содержит web worker. Для работы пакета необходимо настроить копирование файла с web worker из пакета в папку со скриптами приложения при сборке. Пример настройки через webpack:

const CopyPlugin = require("copy-webpack-plugin");

configureWebpack: {
  plugins: [
    new CopyPlugin([{
          // Путь к файлу в пакете
          from: "node_modules/@it-enterprise/digital-signature/src/euscp.worker.js",
          // Путь к файлу в public приложения
          to: "js/euscp.worker.js"
    }])
  ]
}

Импорт

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",
    // id пользователя (для сохранения ключей и предпочитаемого типа ключа) (строка, или функция, возвращающая строку)
    userId, 
    // Путь к API ЕЦП
    location.pathname + "api/ds/",
    // Путь к web worker
    "js/euscp.worker.js") 
  );
// Возвращает текущий тип ключа (файловый, аппаратный, облачный)
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
);

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

Провайдеры облачныч ключей есть 4х видов:

  • работающие через QR код (Дія.Підпис, SmartID, CloudKey, ПУМБ)
  • работающие через ID пользователя (DepositSign, ESign, Вчасно, ДПС)
  • Гряда + сервис подписи
  • vToken (Укргазбанк, Банк Альянс)

Получение списока провайдеров облачных ключей

const ksps = ds.KSPs;

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

import { EUSignCP.KSPSettings } from "@it-enterprise/digital-signature";
// Провайдер облачных ключей
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 { Models.EndUserKSP } from "@it-enterprise/digital-signature";
// Тип провайдера облачных ключей
enum EndUserKSP = {
  // API ИИТ. Провайдеры с этим API поддерживают подписание только 1 файла за раз, сейчас все провайдеры перешли на API PB
  IIT,
  // API ИИТ, поддерживает подписание нескольких файлов за раз
  PB,
  // Дія.Підпис
  DIIA,
  // Подписание ключами с Гряды через сервис подписи
  GRYADA,
  // API vToken. Используется в Укргазбанк, Банк Альянс
  VTOKEN
}

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

Провайдеры с API ИИТ

Провайдеры с API ИИТ имеют тип IIT или PB
Провайдеры с типом IIT могут создавать только 1 подпись за раз, провайдеры с типом PB - несколько
Оба требуют подтверждение операций создания подписей через соответствующие приложения
Подтвердение выполнения операции осуществляется либо через сканирование QR кода, либо через PUSH уведомления
Провайдеров, использующих QR код, можно определить по полю needQRCode

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

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

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

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

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

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

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

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

Для провайдеров, не использующих QR код, необходимо предоставлять пользователю поле ввода идентификатора
Идентификатор пользователя необходимо передавать в функцию считывания ключа
При выполнении операции подписания или считывании ключа с getCerts = true, пользователю в приложение придёт PUSH уведомление и он должен будет подтвердить операцию

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

// Предоставить пользователю возможность выбрать провайдера ключей
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);

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

Дія.Підпис

Для Дія.Підпис использование библиотеки аналогично провайдеру с API ИИТ с QR кодом

Провайдеры с API vToken

Для провайдеров с API vToken сначала нужно авторизироваться и получить список ключей, доступных пользователю:

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

// Объект KSP из списка ds.KSPs
const ksp = ds.KSPs[0];
// Логин и пароль
const userAuthData = new Models.KSPUserAuthData(
  login,
  password
);

const keyMediasResponse = await this.ds.getKeyMediasKSP(ksp, userAuthData);

Структура объекта keyMediasResponse:

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

/**
 * Ответ на запрос получения списка ключей пользователя в облачного провайдера
 */
class KSPKeyMediasResponse {
  // Токен авторизации
  token: string;
  // Включён ли у пользователя второй фактор авторизации 
  isTwoFactor: boolean;
  // Спикок ключей, доступных пользователю
  keys: Array<KSPKeyMedia>;
}

/**
 * Информация про ключ пользователя облачного провайдера
 */
export class KSPKeyMedia {
  // Идентификатор ключа
  keyId: string;
  // Отображаемое имя ключа
  visibleName: string;
  // Владелец ключа
  subject: string;
  // ЦСК, который выдал ключ
  issuer: string;
  // Является ли ключ цифровой печатью
  isStamp: boolean;
}

Считать выбранный ключ:

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

// Предоставить пользователю возможность выбрать ключ
const key = keyMedias.keys[0];
const keyAuthData = new Models.KSPPrivateKeyAuthData(
  // Пароль от выбранного ключа, предоставить ввести пользователю
  keyPassword, 
  // Токен авторизации
  keyMediasResponse.token, 
  // Код двухфакторной авторизации (Google Authenticator), если она включена на аккаунте
  twofaCode);

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

Важно! Если на аккаунте пользователя включена двухфакторная авторизация, перед каждой операцией подписания нужно передавать код двухфакторной авторизации. Для этого нужно вызывать функцию setTwoFactorCodeKSP, в которую передавать код, который укажет пользователь.
Если подписание выполняется сразу после считывания ключа, можно использовать тот же код.


if (keyMediasResponse.isTwoFactor) {
  await this.ds.setTwoFactorCodeKSP(this.twofaCode);
}

const signResult = await this.ds.signData(...);

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

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

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

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

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

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

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

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

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

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

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

class EndUserSignContainerInfo {
  // Тип контейнера подписи
  type: EndUserSignContainerType;
  // Уточняющий тип подписи
  subType: EndUserCAdESType | EndUserXAdESType | EndUserASiCType;
  // Тип подписи в ASiC контейнере (только для ASiC контейнеров)
  asicSignType: EndUserASiCSignType;
  // Уровень подписи
  signLevel: EndUserSignType | EndUserXAdESSignLevel | EndUserPAdESSignLevel;
}
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";

Уровни подписей CAdES

export declare const EU_SIGN_TYPE_CADES_BES = 1;
export declare const EU_SIGN_TYPE_CADES_T = 4;
export declare const EU_SIGN_TYPE_CADES_X_LONG = 16;
export declare enum EndUserSignType {
  // Базовая подпись
  CAdES_BES,
  // Подпись с меткой времени
  CAdES_T,
  // Подпись для длительного хранения с полными данными для проверки
  CAdES_X_Long
}
import { EUSignCP.EndUserConstants.EndUserSignType } 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";

Уровни подписей XAdES

export declare const EU_XADES_SIGN_LEVEL_B_B = 1;
export declare const EU_XADES_SIGN_LEVEL_B_T = 4;
export declare const EU_XADES_SIGN_LEVEL_B_LT = 16;
export declare enum EndUserXAdESSignLevel {
  // Базовая подпись
  B_B,
  // Подпись с меткой времени
  B_T,
  // Подпись для длительного хранения с полными данными для проверки
  B_LT
}
import { EUSignCP.EndUserConstants.EndUserXAdESSignLevel } from "@it-enterprise/digital-signature";

Уровни подписей PAdES

export declare const EU_PADES_SIGN_LEVEL_B_B = 1;
export declare const EU_PADES_SIGN_LEVEL_B_T = 4;
export declare enum EndUserPAdESSignLevel {
  // Базовая подпись
  B_B,
  // Подпись с меткой времени
  B_T
}
import { EUSignCP.EndUserConstants.EndUserPAdESSignLevel } 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,
  signLevel: EndUserXAdESSignLevel.B_LT
};
// Формат PAdES
const padesformat = {
  type: EndUserSignContainerType.PAdES,
  signLevel: EndUserPAdESSignLevel.B_T
};
// Внутренняя CAdES подпись
const cadesformat {
  type: EndUserSignContainerType.CAdES,
  subType: EndUserCAdESType.Enveloped,
  signLevel: EndUserSignType.CAdES_X_Long
};

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);