Программная работа с ЭЦП

Добрый день. Пользуюсь программой Технокад-Экспресс, которая работает с ЭЦП, выданным «УЦ Технокад».
Стоит задача подписать файл этой подписью в своей программе: для бинарного файла создать имя_файла.sig, который будет являться его валидной цифровой подписью

В криптографии я полный ноль, не знаю с чего начать, чтобы побыстрее разобраться с даным вопросом.

Что известно о предмете:
1) Язык программирования: C#
2) Технокад-Экспресс использует программу Крипто-ПРО для работы с сертификатами
3) Сайт-получатель использует что-то вроде CAPICOM для работы с ЭЦП
4) ЭЦП хранится в реестре
5) Экспортированная на флешку ЭЦП состоит из файлов: header.key masks.key masks2.key name.key primary.key primary2.key
6) Стандарт подписи PKCS#7, кодировка DER
7) Информация из документации: Расчет хэш-сумм ГОСТ Р 34.11-94 www.w3.org/2001/04/xmldsig-more#gostr3411
Формирования подписи ГОСТ Р 34.10-2001 www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411
Каноникализация Exclusive XML Canonicalization от 18 July 2002 www.w3.org/2001/10/xml-exc-c14n#

Скачал библиотеку BouncyCasle, пытаюсь разобраться в ней. Смущает, что там реализован не PKCS#7, а PKCS#12, эти стандарты обратно совместимы?

Подскажите, пожалуйста, в какую сторону следует копать, какие-нибудь сайты с примерами?
  • Вопрос задан
  • 15804 просмотра
Решения вопроса 1
Juralis
@Juralis
К сожалению, C# не знаю, могу поделиться своей функцией на IronPython. Порядок действий, классы и методы будут одинаковые.

from System.Security.Cryptography import Pkcs
from System.Security.Cryptography.X509Certificates import X509Store, OpenFlags, X509Certificate2Collection,\
    X509Certificate2, X509Certificate2UI, StoreName

def sign(content, tp):
    store = X509Store(StoreName.My)
    store.Open(OpenFlags.ReadOnly)
    storecollection = X509Certificate2Collection(store.Certificates)
    myCert = None
    for cert in storecollection:
        if cert.Thumbprint.ToLower == tp.ToLower:
            myCert = cert
    if not myCert:
        return None
    else:
        contentInfo = Pkcs.ContentInfo(content)
        signedCms = Pkcs.SignedCms(contentInfo, True)
        cmsSigner = Pkcs.CmsSigner(myCert)
        signedCms.ComputeSignature(cmsSigner)
        sign = signedCms.Encode()
        return sign

Соответственно, тут на входе байты файла и строка с отпечатком (Tumbprint, его можно посмотреть в свойствах сертификата, но если захотите скопировать прямо от туда, то нужно убрать пробелы)
Вместо передачи отпечатка можно прямо просить выбрать сертификат. У класса X509Certificate2UI есть метод SelectFromCollection, который показывает стандартное окошко выбора сертификата и возвращает коллекцию с выбранными сертификатами.
Касательно того, что это криптопровайдер от КриптоПро — в общем-то, в данном случае не имеет значения.

Ну, соответственно, остаётся прочитать файл и сохранить байты подписи в имя_файла.sig
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
ystr
@ystr
Рекомендую первично ознакомиться с понятием Crypto API и для начала почитать мою давнюю статью Использование Crypto API. Также рекомендую почитать форум фирмы Крипто-ПРО. Различных примеров там приводится множество.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы