crypto-pro from vgoma — GithubHelp

crypto-pro from vgoma - GithubHelp ЭЦП
Содержание
  1. Введение.
  2. Angular (es modules typescript)
  3. Capicom
  4. Certificate enrollment api
  5. Certificate services
  6. Cryptopro
  7. License
  8. Базовые криптографические функции
  9. Встраивание в ос unix
  10. Встраивание на уровне ядра
  11. Встраивание скзи «криптопро csp 5.0»
  12. Высокоуровневые функции обработки криптографических сообщений
  13. Доступные методы
  14. Загрузка сертификата в хранилище.
  15. Загрузка файла отозванных сертификатов.
  16. Запуск режима разработки
  17. Запуск тестов
  18. Зачем мне этот пакет?
  19. Использование com интерфейсов
  20. Использование скзи в составе программных продуктов ооо «крипто-про»
  21. Использование скзи в стандартном программном обеспечении
  22. Лицензия
  23. Методы объекта cryptopro
  24. Методы объекта сертификата
  25. Миграция с версии 1 на 2
  26. Настройка плагина для firefox (до версии 52):
  27. Низкоуровневые функции обработки криптографических сообщений
  28. Отладка в windows
  29. Ошибка параметр задан неверно. (0x80070057)
  30. Поддерживаемые браузеры
  31. Поддерживаемые скзи
  32. Подключение на уровне cryptoapi 2.0 в windows
  33. Подключение на уровне csp в windows
  34. Полезные ссылки:
  35. Постороение цепочки сертификата.
  36. Прверка подписи.
  37. Примеры
  38. Примеры использования средств криптографической защиты
  39. Проверка пакета перед публикацией в npm
  40. Проверка работы примеров с react и angular
  41. Реализация взаимодействия с криптопро csp на c.
  42. Создание python библиотеки.
  43. Тем, кто хочет помочь
  44. Теоритическая часть.
  45. Установка
  46. Установка криптопро csp в linux / osx
  47. Установка криптопро эцп browser plug-in в linux
  48. Установка сертификатов в linux
  49. Функции кодирования/декодирования
  50. Функции работы со справочниками сертификатов
  51. Функциональность cryptoapi 2.0
  52. Заключение.

Введение.

В одной из поддерживаемых мной систем цифровая подпись сообщений проверялась с помощью КриптоПро CSP и библиотека отвечающая за это функцию периодически падала с ошибкой. Библиотека эта писалась в спешке и не мной, поэтому я решил переделать ее “по-человечески” и оформить в виде python модуля. Ниже я опишу процесс разработки и опишу с какими трудностями я столкнулся.

Angular (es modules typescript)

Запуск в режиме разработки:

ЭЦП:  КАКУЮ КРИПТОПРО СКАЧАТЬ ДЛЯ ЭЦП И ПРОГРАММЫ ДЛЯ РАБОТЫ С ЭЦП WINDOWS

Запуск в продакшн режиме:

npm run build
npm run serve

Capicom

CAPICOM (реализованный в файле capicom.dll) предоставляет COM интерфейс, использующий основные функции CryptoAPI 2.0. Этот компонент является добавлением к COM интерфейсу Certificate Enrollment Control (xenroll.dll), который реализуют клиентские функции генерации ключей, запросов на сертификаты открытых ключей и обмена с центром сертификации.

С выпуском данного компонента стало возможным использование функций формирования и проверки электронной цифровой подписи, построения и проверки цепочек сертификатов, взаимодействия с различными справочниками сертификатов (включая Active Directory) с использованием Visual Basic, C , JavaScript, VBScript и среды разработки Delphi. Использование CAPICOM позволяет реализовать функциональность «тонкого» клиента в интерфейсе браузера Internet Explorer.

Компонент CAPICOM является свободно распространяемым и поставляется в составе Redistributable инструментария разработчика Microsoft Platform SDK.

Certificate enrollment api

COM интерфейс Certificate Enrollment API (реализованный в файле certenroll.dll, ранее xenroll.dll) предназначен для использования ограниченного количества функций CryptoAPI 2.0, связанных с генерацией ключей, запросов на сертификаты открытых ключей и обработкой сертификатов, полученных от Центра Сертификации, с использованием языков программирования Visual Basic, C , JavaScript, VBScript и среды разработки Delphi.

Именно этот интерфейс используют различные Центры Сертификации (Verisign, Thawte и т. д.) при формировании сертификатов открытых ключей пользователей на платформе Windows.

Certificate services

Certificate Services включает в себя несколько COM интерфейсов, позволяющих изменить функциональность Центра Сертификации, входящего в состав ОС Windows Server. При помощи данных интерфейсов возможно изменить:

  • обработку поступающих от пользователей запросов на сертификаты
  • состав данных (в том числе дополнений X.509), записываемых в издаваемые центром сертификаты
  • способ публикации (хранения) изданных центром сертификатов.

Cryptopro

Единое, асинхронное API для взаимодействия с КриптоПРО ЭЦП Browser Plug-In

License

Licensed as MIT. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.

Базовые криптографические функции

К базовым функциям относятся функции:

  • Функции инициализации (работы с контекстом). Эти функции предоставляют приложению возможность выбрать определенный криптопровайдер по типу имени или по требуемой функциональности.
  • Функции генерации ключей. Эти функции предназначены для формирования и хранения криптографических ключей различных типов.
  • Функции обмена ключами. Эти функции предназначены для того, чтобы приложения могли обмениваться различными типами ключевой информации для обеспечения взаимодействия между собой.
  • Функции хэширования и ЭП. Эти функции предназначены для вычисления значения хэш-функции и формирования/проверки ЭП данных.
  • Функции шифрования/расшифрования данных. Эти функции предназначены для выполнения операций шифрования и расшифрования данных.

По своей функциональности базовые функции повторяют низкоуровневый интерфейс CSP.

Встраивание в ос unix

Для подключения СКЗИ к прикладному ПО необходимо пользоваться интерфейсом CAPILite. Подробности в документации на CAPILite.

Встраивание на уровне ядра

Для встраивания на уровне ядра пользуйтесь рекомендациями из Особенности использования интерфейса уровня ядра в OC Linux и Особенности использования интерфейса уровня ядра в Windows .

Встраивание скзи «криптопро csp 5.0»

Иерархическая архитектура криптографических функций в операционной системе Windows позволяет использовать российские криптографические алгоритмы, реализованные в «КриптоПро CSP 5.0» на самых различных уровнях.

Высокоуровневые функции обработки криптографических сообщений

Именно эта группа функций (Simplified Message Functions) в первую очередь предназначена для использования в прикладном ПО. С помощью этих функций можно:

  • Зашифровать/расшифровать сообщение от одного пользователя к другому.
  • Подписать данные.
  • Проверить подпись данных.

Эти функции (как и функции низкого уровня) оперируют сертификатами открытых ключей X.509 для адресации отправителя/получателя данных. В качестве формата данных используется формат PKCS#7 или CMS.

Доступные методы

Список доступных методов можно посмотреть в файле src/api.js.

Загрузка сертификата в хранилище.

Для того, чтобы загрузить сертификат в хранилище нужно выполнить следующие шаги:

  1. Считать сертификат из файла
  2. Открыть хранилище сертификатов
  3. Положить в него сертификат
  4. Закрыть хранилище

Тут меня ждал первый ньюанс, что в CPCSP нет функции для чтения сертификата из файла, поэтому ее нужно будет написать вручную. Она выглядит следующим образом:

typedef struct CERT {
    BYTE *content;
    DWORD size;
} CERT;

CERT readFile(char *filename)
{
    CERT cert = {NULL, 0};
    FILE *fCert;

    fCert = fopen(filename, "r");
    if (fCert)
    {
		fseek(fCert, 0, SEEK_END);   
		cert.size = ftell(fCert);
		rewind(fCert);

	    cert.content = (unsigned char *)malloc(cert.size * sizeof(unsigned char));
	    fread(cert.content, cert.size, 1, fCert);
    }
    else
    {
		perror("Error open certificate file");
    }
    fclose(fCert);

  return cert;
}

PCCERT_CONTEXT ReadCertificateFromFile(char *filename)
{
    CERT fileCert; 
    PCCERT_CONTEXT cert = NULL;

    fileCert = readFile(filename);
		
    cert = CertCreateCertificateContext(
		X509_ASN_ENCODING,
		fileCert.content,
		fileCert.size
	);
    
    if (!(cert))
    {
		perror("Error create cert");
    }

  return cert;
}

В коде выше файл считывается специальную структуру CERT, которая содержит размер и содержимое сертификата. Затем на основе этой информации формируется структура PCCERT_CONTEXT, которая в дальнейшем будет загружаться в хранилище CPCSP.

Далее в описании функций будут использоваться следующие коды ошибок:

# define OPERATION_SUCCESS        0
# define OPEN_STORE_ERROR         1
# define ADD_CERT_TO_STORE_ERROR  2
# define CLOSE_STORE_ERROR        3
# define ADD_CRL_TO_STORE_ERROR   4
# define STR_TO_BIN_LEN_ERROR     5
# define STR_TO_BIN_CONTENT_ERROR 6
# define VERIFY_MSG_SIGNATURE     7
# define GET_CERT_CHAIN_ERROR     8
# define READ_CERT_ERROR          9
# define READ_CRL_ERROR           10

Функция загрузки сертификата в хранилище будет выглядеть следующим образом:

int LoadCertificateToSystemStore(char *cert_file_path, char *store_name)
{
    HCERTSTORE     cpcsp_cert_store = NULL;
    PCCERT_CONTEXT cert_context;

    cert_context = ReadCertificateFromFile(cert_file_path);
    if (!cert_context)
	return READ_CERT_ERROR;
  
    cpcsp_cert_store = CertOpenSystemStore(0, store_name);

    if (!cpcsp_cert_store)
	return OPEN_STORE_ERROR;

    if (!CertAddCertificateContextToStore(
	    cpcsp_cert_store,
	    cert_context,
	    CERT_STORE_ADD_REPLACE_EXISTING,
	    NULL))
	return ADD_CERT_TO_STORE_ERROR;

    if (!CertCloseStore(cpcsp_cert_store, 0))
	return CLOSE_STORE_ERROR;

    if (cert_context)
	CertFreeCertificateContext(cert_context);

    return OPERATION_SUCCESS;
}

В этой функции считывается файл сертификата (функция ReadCertificateFromFile), затем открываем системное хранилище методом CertOpenSystemStore. Если системное хранилище открылось успешно, то с помощью метода CertAddCertificateContextToStore, сертификат загрузается в хранилище. И в заключении хранилище закрывается функцией CertCloseStore.

Нужно отметить что функция CertOpenSystemStore ипользуется только для чтения системных хранилищ (root, ca, my), для остальных надо использовать CertOpenStore.

Загрузка файла отозванных сертификатов.

Функции чтения списка отозванных сертификатов(CRL) и загрузки их в хранилище идентичны функциям работы с сертификатами, за тем исключением, что для их чтения и загрузки используются функции CPCSP c CRL вместо Certificate в названии функции. Например CertAddCertificateContextToStore будет выглядеть как CertAddCRLContextToStore.

Таким образом код для загруки CRL будет таким:

int LoadCRLToSystemStore(char *cert_file_path, char *store_name)
{
    HCERTSTORE    cpcsp_cert_store = NULL;
    PCCRL_CONTEXT crl_context;

    crl_context = ReadCRLFromFile(cert_file_path);
    if (!crl_context)
	return READ_CRL_ERROR;
  
    cpcsp_cert_store = CertOpenSystemStore(0, store_name);

    if (!cpcsp_cert_store)
	return OPEN_STORE_ERROR;

    if (!CertAddCRLContextToStore(
	    cpcsp_cert_store,
	    crl_context,
	    CERT_STORE_ADD_REPLACE_EXISTING,
	    NULL))
	return ADD_CRL_TO_STORE_ERROR;

    if (!CertCloseStore(cpcsp_cert_store, 0))
	return CLOSE_STORE_ERROR;

    if (crl_context)
	CertFreeCRLContext(crl_context);

  return OPERATION_SUCCESS;
}

Запуск режима разработки

Устанавливаем зависимости:

Во время работы с кодом необходим запущенный сборщик:

И пример, на котором можно тестировать изменения.
Удобнее всего тестировать на примере с тэгом script, тк он отвязан от фреймворков
и использует сборку в формате UMD из папки dist/, постоянно обновляемую пока работает
сборщик. Запускаем его таким образом:

После выполнения npm link ../../ в директории examples/script-tag/node_modules папка crypto-pro-js станет ярлыком,
указывающим на папку содержащую локально собранный пакет.

Запуск тестов

Тесты написаны с использованием Jest:

Зачем мне этот пакет?

КриптоПРО ЭЦП Browser Plug-In доступен в разных браузерах в двух версиях.
Асинхронной (в современных браузерах) и синхронной (в браузерах постарше).
С помощью этого пакета можно не писать реализацию под каждую версию плагина дважды.
И вместо этого
и этого
написать это (UMD):

или это (ES Modules Typescript):

Использование com интерфейсов

«КриптоПро CSP 5.0» может быть использовано из COM интерфейсов, разработанных Microsoft.

  • CAPICOM 1.0 (CAPICOM 2.0);
  • Certificate Services;
  • Certificate Enrollment Control.

Использование скзи в составе программных продуктов ооо «крипто-про»

СКЗИ «КриптоПро CSP 5.0» используется в составе следующих программных продуктов ООО «КРИПТО-ПРО» (включая, но не ограничиваясь):

  • КриптоПро УЦ;
  • Службы УЦ (КриптоПро OCSP, КриптоПро TSP, КриптоПро SVS, КриптоПро Revocation Provider);
  • КриптоПро DSS;
  • КриптоПро HSM;
  • КриптоПро NGate;
  • КриптоПро ЭЦП Browser plug-in;
  • КриптоАРМ;
  • КриптоПро EFS;
  • КриптоПро Office Signature;
  • Secure Pack RUS.

Кроме того, обеспечена техническая совместимость СКЗИ с продуктами:

  • КриптоПро SSF;
  • КриптоПро PDF.

Использование скзи в стандартном программном обеспечении

Программное обеспечение СКЗИ позволяет использовать российские криптографические алгоритмы и сертификаты открытых ключей (ключей проверки ЭП) стандарта X.509 совместно со следующим программным обеспечением (включая, но не ограничиваясь):

Лицензия

MIT

Методы объекта cryptopro

*Методы getContainerCertificates и getAllContainerCertificates позволяют получить сертификаты из закрытых ключей, записанных на обыкновенную флэшку

Методы объекта сертификата

Сертификат предоставляет следущее API:

Миграция с версии 1 на 2

Внесены следующие изменения:

  • Пакет собран в форматах:
    • UMD, в папке dist/, для подключения через тэг script. Объект window.cryptoPro доступен глобально.
    • ES Modules, в папке lib/, для использования с разными системами сборки.
      Методы API импортируются напрямую из npm пакета.
  • В UMD версии переименован глобальный объект с window.CryptoPro на window.cryptoPro
  • Переименованы общие методы:
  • Убран метод signDataXML
  • Переименованы методы сертификата:
  • Результат методов сертификата getOwnerInfo и getIssuerInfo
    изменился с { descr, title, translated } на { description, title, isTranslated }
  • Принципиальная реализация методов, обращающихся к Крипто ПРО не изменилась.
    Получение сертификатов, создание подписи, проверка корректности настроек работают по-прежнему.
  • Убрана поддержка IE8 (Крипто ПРО его больше не поддерживает)
  • Убрана поддержка КриптоПРО CSP версий ниже 4.0
  • Убрана поддержка КриптоПРО ЭЦП browser plug-in версий ниже 2.0
  • Доработана обработка ошибок, выбрасываемых из Крипто ПРО
  • При написании кода будут работать автодополнения и подсказки
  • Исправлена проблема работы библиотеки с UglifyJs
  • Методы API доступны напрямую:

В версии 1:

В версии 2 (UMD):

В версии 2 (ES Modules):

Настройка плагина для firefox (до версии 52):

После настройки плагина на страницах, запрашивающих работу с ЭП в панели навигации, рядом с url будет кнопка,
позволяющая «разрешить и запомнить» использование установленного плагина.

cd /usr/lib/mozilla/plugins

cp /opt/cprocsp/lib/amd64/libnpcades.so.2.0.0 ./
ldd libnpcades.so.2.0.0

cp /opt/cprocsp/lib/amd64/libnpcades.so.2.0.0 ./libnpcades.so
ldd libnpcades.so

Перезапустите Firefox, и убедитесь в наличии CryptoPRO Cades plugin (см. Menu -> Addons).

Низкоуровневые функции обработки криптографических сообщений

Данная группа функция (Low Level Message Functions) предназначена для аналогичных целей, что и группа высокоуровневых функций, но обладает большей функциональностью. Вместе с тем большая функциональность требует от прикладного программиста более детальных знаний в области прикладной криптографии.

Отладка в windows

Для работы с любым отладчиком контроль целостности в драйвере должен быть отключен. Для этого следует в реестре значение HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerCProIntegrityCheckMode установить в 0. После этого необходимо перестартовать сервис.

Ошибка параметр задан неверно. (0x80070057)

Если при попытке подписать сообщение с использованием PKCS#7 подписи падает такая ошибка, то читайте этот issue

Поддерживаемые браузеры

Список необходимых полифиллов (подключаются самостоятельно):

  • Promise
  • EventTarget.addEventListener
  • Array.prototype.forEach
  • Array.prototype.map

Поддерживаемые скзи

КриптоПРО CSP (v4.0 ) рекомендуется использование только сертифицированных версий. Инструкция по установке:

КриптоПРО ЭЦП browser plug-in (v2.0.12438 ).

Инструкция по установке плагина в Linux. В Windows и OSX следуйте указаниям программы-установщика.

Инструкция по установке сертификатов в систему для Linux / OSX.

Подключение на уровне cryptoapi 2.0 в windows

«КриптоПро CSP 5.0» может быть подключено к прикладному программному обеспечению (как и любой другой криптопровайдер, поставляемый с ОС Windows) через интерфейс CryptoAPI 2.0, подробное описание которого приведено в программной документации MSDN (Microsoft Developer Network).

Подключение на уровне csp в windows

В ОС Windows СКЗИ «КриптоПро CSP 5.0» может быть непосредственно подключено к прикладному программному обеспечению путем загрузки модуля cpcspi.dll с использованием функции LoadLibrary(). При такой реализации прикладному ПО доступен лишь ограниченный набор низкоуровневых криптографических функций, соответствующий интерфейсу Microsoft CSP.

Примечание. При использовании СКЗИ под управлением ОС iOS загрузка библиотек при помощи функции LoadLibrary() невозможна.

Полезные ссылки:

  1. Документация по КриптоПро
  2. Cryptography Reference MS
  3. CryptoAPI: How to import a certificate
  4. ЭЦП в браузере
  5. py_cpcsp

Постороение цепочки сертификата.

Код функции проверки цепочки сертификатов выглядит следующим образом

int VerifyCertChain(char *certFilePath)
{
    PCCERT_CONTEXT           pCertContext;
    PCCERT_CHAIN_CONTEXT     pChainContext;
    CERT_ENHKEY_USAGE        EnhkeyUsage;
    CERT_USAGE_MATCH         CertUsage;
    CERT_CHAIN_PARA          ChainPara;

    /*
      инициализация парметров поиска и сопоставления, которые 
      будут использоваться для построения цепочки сертификатов 
    */
    EnhkeyUsage.cUsageIdentifier = 0;
    EnhkeyUsage.rgpszUsageIdentifier = NULL;
    CertUsage.dwType = USAGE_MATCH_TYPE_AND;
    CertUsage.Usage  = EnhkeyUsage;
    ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
    ChainPara.RequestedUsage=CertUsage;
 
    pCertContext = ReadCertificateFromFile(certFilePath);

    if (!CertGetCertificateChain(
	    NULL,
	    pCertContext,
	    NULL,
	    NULL,
	    &ChainPara,
	    0,
	    NULL,
	    &pChainContext))
    {
		perror("The chain could not be created");
    }
	
	int result = pChainContext->TrustStatus.dwErrorStatus;

    if (pChainContext)
    {
		CertFreeCertificateChain(pChainContext);
    }
	
    return result;
}

Помимо настроек цепочки, тут вызывается функция CertGetCertificateChain, которая формирует собственно цепочку сертификатов и записывает ее в структуру PCCERT_CHAIN_CONTEXT. В данной структуре поле TrustStatus отвечает за статус опреации, если цепочка построена корректно, то dwErrorStatus будет 0, иначе будет записан код ошибки.

Прверка подписи.

Для начала я подумал сорфировать самоподписной сертификат для проверки функционирования функции, но оказалось, что CPCSP не поддерживает их, поэтому я создал сертификат в Тестовом УЦ КриптоПро. Я не буду описывать данный процесс, так как к библиотике он имеет посредственное отношение.

Также надо отметить, что сертификат ЦС, надо загрузить в хранилище “Доверенные корневые…”. Иначе сгенерированный тестовый сертификат не установиться и плагин для ЭЦП не будет корректно работать. Код функции проверки подписи приведен ниже:

int VerifySignedMessage(char *signature)
{
    DWORD blob_size = 0;
    /* 
       определяем размер выходного der блоба
       для подписанного сообщения
    */
    if (!CryptStringToBinaryA(
	    signature,
	    strlen(signature),
	    CRYPT_STRING_BASE64,
	    NULL,
	    &blob_size,
	    NULL,
	    NULL))
	return STR_TO_BIN_LEN_ERROR;	


    /*
       заполняем блоб подписанного сообщения
     */
    BYTE *msg_blob;
    msg_blob = (BYTE *)malloc(blob_size);
    if (!CryptStringToBinaryA(
	    signature,
	    strlen(signature),
	    CRYPT_STRING_BASE64,
	    msg_blob,
	    &blob_size,
	    NULL,
	    NULL))
	return STR_TO_BIN_CONTENT_ERROR;	

    /*
      выполняем проверку подписи
     */
    CRYPT_VERIFY_MESSAGE_PARA verify_params;

    verify_params.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
    verify_params.dwMsgAndCertEncodingType = ENCODING_TYPE;
    verify_params.hCryptProv = 0;
    verify_params.pfnGetSignerCertificate = NULL;
    verify_params.pvGetArg = NULL;
    
    if(!CryptVerifyMessageSignature(
        &verify_params,
        0,
        msg_blob,
        blob_size,
        NULL,
        NULL,
        NULL))
	return VERIFY_MSG_SIGNATURE;
    
    return OPERATION_SUCCESS;
}

Код снабжен коментариями, которые поясняют за что какой кусок кода отвечает.

Также надо отметить что функция CryptStringToBinaryA вызывается 2 раза, первый для получения размер подписи, а второй, чтобы получить данные раскодированные из base64 данные. Ну и затем подпись соответственно проверяется.

Примеры

Для их запуска необходим NodeJS LTS.

Примеры использования средств криптографической защиты

СКЗИ «КриптоПро CSP 5.0» поставляется с тестовым программным обеспечением, содержащим примеры вызовов основных функций CryptoAPI 2.0. Большое количество примеров использования функций CryptoAPI 2.0, CAPICOM, Certificate Services содержится в документации MSDN и в инструментарии разработчика Platform SDK.

На сервере Крипто-Про ведется Форум КриптоПроWorld Wide Web link

Примечание. Подробную информацию об особенностях реализации и использования СКЗИ «КриптоПро CSP 5.0» см. в документах «КриптоПро CSP. Описание реализации» и «КриптоПро CSP. Руководство администратора безопасности. Использование СКЗИ под управлением ОС Windows», входящих в комплект поставки СКЗИ.

Проверка пакета перед публикацией в npm

Необходимо протестировать работу в заявленных браузерах, сделав это на локально запакованной версии пакета.
Для этого собираем пакет:

npm run package
mv package ..

Важно переместить папку package куда-нибудь выше для избежания конфликтов при линковке с текущим package.json.

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

Проверяем работу примеров в режимах разработки и продакшн.

После завершения экспериментов можно удалить глобальную ссылку из директории ../../../package таким образом:

Проверка работы примеров с react и angular

React и Angular используют версию сборки пакета в формате ES модулей из директории lib/.
Для их запуска необходимо сначала собрать пакет выполнив:

После этого из папки examples/angular или examples/react залинковать пакет:

И запустить пример в одном из двух режимов. В режиме разработки:

или в режиме продакшн:

npm run build
npm run serve

Реализация взаимодействия с криптопро csp на c.

Так как КриптоПро CSP(CPCSP) является доработкой CryptoApi от Microsoft, то большая часть примеров из официальной документации подходит идля “КриптоПро”. Чем я собствеено говоря и пользовался при написании модуля, так как с примерами у самого КриптоПро не очень все хорошо.

Создание python библиотеки.

После того, как все функции написаны, то можно приступуть к реализации С обертки для python библиотеки и написанию тестов.
Для начала опишем заголовочный файл, который будет содержать описание вызываемых функций и исключений:

#ifdef __linux__
	#include <Python.h>
#elif __APPLE__
	#include <Python/Python.h>
#endif

#ifndef LIBSIGNATURE_H_
#define LIBSIGNATURE_H_

/* 
   Список экспортируемых функций
 */
PyObject * PyLoadCertificate(PyObject *self, PyObject *args);
PyObject * PyLoadCRL(PyObject *self, PyObject *args);
PyObject * PyVerifyCertChain(PyObject *self, PyObject *args);
PyObject * PyVerifySignedMessage(PyObject *self, PyObject *args);

/*
  Типы исключений различных ситуаций
 */
extern PyObject *PyOpenStoreError;
extern PyObject *PyAddCertToStoreError;
extern PyObject *PyCloseStoreError;
extern PyObject *PyAddCrlToStoreError;
extern PyObject *PyStrToBinLenError;
extern PyObject *PyStrToBinContentError;
extern PyObject *PyVerifyMsgSignatureError;
extern PyObject *PyGetCertChainError;
extern PyObject *PyReadCertError;
extern PyObject *PyReadCrlError;

#endif

Как видно из этого файла, на каждый код ошибки С функций, будет соответствовать свое исключение. Реализацию самих функций можно посмотреть в файле py_cpcsp.cрепозитория.

Код оберки для библиотеки выглядит следующим образом:

Тем, кто хочет помочь

Буду благодарен за расширение/улучшение/доработку API.
Вам будут полезны примеры,
предоставляемые Крипто ПРО.

Теоритическая часть.

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

Все ключи крипто про хранит в своих хранилищах, таких как root, ca, my. Чтобы в них загрузить сертификат в поставке Криптопро CSP идет специальная утилита certmgr. Синтаксих ее работы таков:

certmgr -inst -store <имя хранилища> -file <файл с сертификатом>

Также для корректной цепочки надо загрузить список отозванных сертификатов. Сделать это можно командой:

certmgr -instl -crl -store <имя хранилища> -file <CRL файл>

Побробную информацию по работе этой утилиты можно получить вызвав:

certmgr -help

Для конкретного сертификата также можно проверить цепочку. Делается это командой:

cryptcp -verify -f <файл сертификата> "text" -errchain

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

Из всего вышесказанного я подумал, что в библиотеке мне нужны будут следующие функции:

  • Загрузка сертификата в хранилище;
  • Загрузка файла отозванных сертификатов;
  • Постороение цепочки сертификата;
  • Проверка подписи.

Установка

Для NPM:

npm install crypto-pro-js

Для Yarn:

Для Bower:

bower install webmasterskaya/crypto-pro-js

Подключение пакета как UMD модуля через тэг script:

Подключение пакета как ES модуля с Typescript или JavaScript:

Список требуемых полифиллов (если необходимы, подключаются самостоятельно):

  • Promise
  • Array.prototype.find

Установка криптопро csp в linux / osx

Процесс установки в OSX незначительно отличается от Linux, поэтому описание приведено на примере дистрибутива семейства Debian (x64).

Некоторые команды могут потребовать запуска с sudo.
Названия файлов и директорий могут отличаться из-за различий в версиях.

После загрузки КриптоПРО CSP для нужной платформы, распакуйте архив:

tar -xzvf linux-amd64_deb.tgz
chmod 777 -R linux-amd64_deb/

Запустите скрипт установки:

linux-amd64_deb/install.sh

Проверьте отсутствиеcprocsp-rdr-gui:

Установите дополнительно cprocsp-rdr-gui-gtk:

dpkg -i linux-amd64_deb/cprocsp-rdr-gui-gtk-64_4.0.0-4_amd64.deb

Дополнительная информация по установке

Установка криптопро эцп browser plug-in в linux

Загрузите КриптоПРО ЭЦП browser plug-in и распакуйте его:

mkdir cades_linux_amd64
tar -xzvf cades_linux_amd64.tar.gz -C cades_linux_amd64

Сконвертируйте rpm в deb пакеты при помощи утилиты alien:

apt-get update && apt-get install alien
cd cades_linux_amd64
alien *

Установите пакеты:

dpkg -i cprocsp-pki-cades_2.0.0-2_amd64.deb
dpkg -i cprocsp-pki-plugin_2.0.0-2_amd64.deb

Проверьте наличие файлов плагина:

ls -la /opt/cprocsp/lib/amd64 | grep libnpcades

    lrwxrwxrwx 1 root root      19 Окт 21 12:33 libnpcades.so -> libnpcades.so.2.0.0
    lrwxrwxrwx 1 root root      19 Окт 21 12:33 libnpcades.so.2 -> libnpcades.so.2.0.0
    -rwxr-xr-x 1 root root 2727236 Июн  8 14:33 libnpcades.so.2.0.0

Установка сертификатов в linux

В OSX процесс схож с Linux.

Подключите USB носитель с ключевыми контейнерами и проверьте результат команды:

/opt/cprocsp/bin/amd64/csptest -keyset -enum_cont -fqcn -verifyc

    CSP (Type:80) v4.0.9009 KC1 Release Ver:4.0.9797 OS:Linux CPU:AMD64 FastCode:READY:AVX.
        AcquireContext: OK. HCRYPTPROV: 16188003
        \.FLASHivanov
        \.FLASHpetrov
        \.FLASHsidorov
        \.FLASHvasiliev
        \.FLASHsmirnov
        OK.
        Total: SYS: 0,020 sec USR: 0,060 sec UTC: 0,180 sec

Скопируйте ключевой контейнер \.FLASH.sidorov на жесткий диск:

/opt/cprocsp/bin/amd64/csptest -keycopy -contsrc '\.FLASHsidorov' -contdest '\.HDIMAGEsidor'

    CSP (Type:80) v4.0.9009 KC1 Release Ver:4.0.9797 OS:Linux CPU:AMD64 FastCode:READY:AVX.
    CryptAcquireContext succeeded.HCRYPTPROV: 38556259
    CryptAcquireContext succeeded.HCRYPTPROV: 38770755
    Total: SYS: 0,000 sec USR: 0,100 sec UTC: 14,920 sec
    [ErrorCode: 0x00000000]

Наличие [ErrorCode: 0x00000000] в завершении каждой команды КриптоПРО говорит о ее успешном выполнении.

Проверьте наличие нового контейнера \.HDIMAGEsidor:

/opt/cprocsp/bin/amd64/csptest -keyset -enum_cont -fqcn -verifyc

    CSP (Type:80) v4.0.9009 KC1 Release Ver:4.0.9797 OS:Linux CPU:AMD64 FastCode:READY:AVX.
    AcquireContext: OK. HCRYPTPROV: 34554467
    \.FLASHivanov
    \.FLASHpetrov
    \.FLASHsidorov
    \.FLASHvasiliev
    \.FLASHsmirnov
    \.HDIMAGEsidor
    OK.
    Total: SYS: 0,010 sec USR: 0,050 sec UTC: 0,130 sec
    [ErrorCode: 0x00000000]

Установите личный сертификат:

/opt/cprocsp/bin/amd64/certmgr -inst -cont '\.HDIMAGEsidor'

Возможно в выводе вы ссылку на сертификат УЦ

При необходимости загрузите сертификат удостоверяющего центра и установите его командой:

/opt/cprocsp/bin/amd64/certmgr -inst -store uroot -file <файл сертификата>.crt

После чего, при проверке установленного личного сертификата вы увидите PrivateKey Link: Yes:

/opt/cprocsp/bin/amd64/certmgr -list -store uMy

Функции кодирования/декодирования

Данные функции предназначены для преобразования (кодирования) из внутреннего представления объектов, используемых в CryptoAPI, во внешнее представление и обратно. В качестве внешнего представления объектов используется формат ASN.1 (Abstracy Syntax Notation One), определенный серией рекомендаций X.680.

Функции работы со справочниками сертификатов

Эта группа функций предназначена для хранения и обработки сертификатов в различных типах справочников. Причем в качестве справочника могут использоваться самые различные типы хранилищ: от простого файла до LDAP.

Функциональность cryptoapi 2.0

Использование интерфейса CryptoAPI 2.0 в ОС Windows преследует две главные цели:

  • Дать прикладному уровню доступ к криптографическим функциям для генерации ключей, формирования/проверки электронной цифровой подписи, шифрования/расшифрования данных. Эта цель достигается путем изолирования прикладного уровня от уровня реализаций криптографических функций. Прикладным программистам не нужно детально изучать особенности реализации того или иного алгоритма или изменять код в зависимости от алгоритма.
  • Изолирование прикладного уровня от криптографических функций позволяет одновременно использовать разные алгоритмы и различные реализации этих алгоритмов, включая аппаратные.

Функционально интерфейс CryptoAPI 2.0 делится на 5 групп.

Заключение.

Процесс создания библиотеки получился трудоемкий, но на выходе получилась рабочая библиотека, которой можно пользоваться. В репозиотории можете найти пакет для работы из python, но также можно использовать только C-ную часть. Для работы С библиотеки нужно выполнить make build_c.

Оцените статью
ЭЦП64