Как работает ЭЦП RSA+SHA1? Как реализовать на C#? Добрый день!
Интегрируемся с платежным шлюзом, который использует для верификации общения ЭЦП RSA+SHA1 с сертификатами X509. Нами был сформирован закртый ключ + сертификат, который мы отправили шлюзу. Шлюз в ответ сформировал сертификат на своей стороне и прислал два файла, CRT и KEY (содержит паблик кей). Насколько я понимаю алгоритм подписи, при отправке мы сначала от подписываемого контента считаем RSA, используя их сертификат(открытый ключ?), затем считаем sha1-хеш от полученного шифра. Вопрос:
1) Правильно ли я описал процесс? или есть еще шаги, которые я упускаю?
2) Сертификат содержит открытый ключ? если так, то нужен ли присланный шлюзом KEY-файл?
Практическая часть.
Реализацию делаем на C#. var content = "data";
var ctr = new X509Certificate2(filename); // путь до crt-файла присланного шлюзом
var provider = ctr.PublicKey.Key as RSACryptoServiceProvider; // если после этой строки посмотрим на provider, то там действительно есть сертификат длинной 2048
var dta = provider.Encrypt(Encoding.ASCII.GetBytes(content), true); // в dta вроде бы 256 байт
var sig = provider.SignData(dta, "SHA1"); // и тут мы ловим исключение "набор ключей не существует"
1) Что я делаю не так? Ключ то вроде есть?
2) если контент длиннее 2048 байт, то я предполагаю возникнут проблемы на этапе получения RSA-шифра. Предусмотрен ли механизм преодоления этой беды? или единственное решение изначальное формирование ключей длинной в 16кб (ну т.е. бОльшей длинны)?
Спасибо.

21 Авг 2019 в 07:11
252 +1
1
Ответы
1

1) Ваша интерпретация процесса ЭЦП правильна. Для подписи данных вы используете закрытый ключ из вашего сертификата, а для верификации шлюз использует свой открытый ключ.
2) Да, сертификат содержит открытый ключ. KEY файл, который вам прислал шлюз, также содержит открытый ключ, но его формат может отличаться от сертификата. Вам нужно использовать открытый ключ из сертификата для проверки подписи.

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

var ctr = new X509Certificate2(filename);
RSACryptoServiceProvider provider = (RSACryptoServiceProvider)ctr.PrivateKey;
byte[] data = Encoding.ASCII.GetBytes(content);
byte[] signature = provider.SignData(data, CryptoConfig.MapNameToOID("SHA1"));

2) Если контент длиннее 2048 байт, то нужно использовать другие алгоритмы подписи, такие как RSA с длиной ключа 3072 или 4096 бит. К сожалению, в стандартной библиотеке .NET Framework поддерживаются только алгоритмы RSA с ключом длиной до 2048 бит. Для использования более длинных ключей вам придется использовать другие библиотеки или реализации, такие как BouncyCastle или OpenSSL.

20 Апр 2024 в 13:06
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 95 924 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир