Open IverCold opened 2 months ago
Здравствуйте!
Полагаю, что вам подойдёт этот пример. Основную роль играют KeyExchangeFormatter
/KeyExchangeDeformatter
, экземпляры которых создаются на основе асимметричного ключа. Симметричный ключ может быть как постоянным (например, храниться в конфигурациионном файле приложения), так и случайным (если будет организован способ передачи параметров симметричного ключа от отправителя к получателю зашифрованных данных).
Я пробовал реализовать этот пример. Дело в том, что я отправляю открытый ключ в Контур, и они возвращают мне строку, которую я должен расшифровать с помощью закрытой части сертификата. Это выглядит вот так:
var encryptedStr = "здесь_длинная_полученная_строка";
var encryptedBytes = Convert.FromBase64String(encryptedStr);
var encryptedStream = new MemoryStream(encryptedBytes);
var privateKeyAlgorithm = (GostAsymmetricAlgorithm)cert.GetPrivateKeyAlgorithm();
var deformatter = privateKeyAlgorithm.CreateKeyExchangeDeformatter();
using (var receiverSessionKey = deformatter.DecryptKeyExchangeAlgorithm(encryptedBytes))
{
var decryptedString = receiverSessionKey.ToString();
}
Но на строке using код падает в ошибки: CryptographicException: ASN.1 encoded byte array contains invalid structure 'Gost_R3410_KeyTransport'. CryptographicException: ASN.1 decode error. SEQUENCE or SET is missing a required element. Offset: 2.
В чём тут может быть проблема?
Вам нужно внимательней посмотреть на указанный пример.
Метод DecryptKeyExchangeAlgorithm()
делает дешифрацию общего секретного ключа, т.е. на вход он получает зашифрованный симметричный ключ. Как я понял, вы передаете ему не ключ, а зашифрованные данные. Для шифрации/дешифрации данных используется поток CryptoStream
.
Помимо зашифрованных данных вы должны как-то получить вектор инициализации и зашифрованный симметричный ключ. На основе ассиметричного алгоритма вы расшифруете симметричный ключ, а потом уже симметричным ключом расшифруете данные. Обычно это делается так.
Я просто подумал, что есть вариант как-то выдернуть часть реализации расшифровки сообщения. Если я правильно понимаю, то речь идёт о расшифровке сообщения, зашифрованного открытым ключом сертификата. А значит его можно расшифровать закрытым ключом сертификата. Подобно объекту RSACryptoServiceProvider, в котором есть методы .Encrypt(byte[]), .Decrypt(byte[]).
Да, действительно, RSA имеет методы Encrypt()
/Decrypt()
. Однако примечательно, что его нет среди методов базового класса AsymmetricAlgorithm
. Судя по коду RSACryptoServiceProvider
, внутри вызываются методы EncryptKey()
/DecryptKey()
, что наводит на мысль, что под данными подразумевается все-таки ключ (симметричного) шифрования, а не сами данные. Вам действительно не передают зашифрованный симметричный ключ, только зашифрованные данные? Если так, то я попробую изучить тему глубже, может что-то и получится. :)
@IverCold Если вопрос решен, предлагаю поделиться решением и закрыть задачу. :)
@AlexMAS Я лучше приложу инструкцию Контура, которую они мне дали. Нужно получить Access Token. Его можно получить по логину-паролю (как мы делаем сейчас), а можно по сертификату (так должно быть безопаснее). Чтобы получить токен по сертификату расшифровать случайный контент, который присылает Контур. Сам же инструкция вот здесь: https://developer.testkontur.ru/doc/openidconnect?about=2
@IverCold Если вопрос решен, предлагаю поделиться решением и закрыть задачу. :)
Ну, я не настолько хорош, чтобы предложить решение в рамках вашей библиотеки = ) Но невероятная благодарность от меня за её существование. Без неё мы бы просто не взлетели - мы используем реализацию raw подписи для Контура/СФР как раз.
Спасибо за обратную связь! :)
Понятно, то есть вам не удалось выполнить аутентификацию по сертификату. А можете прикрепить файл с base64 этого encrypted_key
, я попробую посмотреть ее через ASN.1-редактор. Может что-то прояснится, что они присылают в ответ. :)
@IverCold Здравствуйте! У вас нет примера encrypted_key
? :)
Добрый день! Я не смог найти в примерах возможности расшифровки текста ассиметричным ключом. Как это можно сделать?