Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Как расшифровать текст при помощи алгоритма ассиметричного ключа #51

Open
IverCold opened this issue Apr 15, 2024 · 10 comments

Comments

@IverCold
Copy link

Добрый день! Я не смог найти в примерах возможности расшифровки текста ассиметричным ключом. Как это можно сделать?

@AlexMAS
Copy link
Owner

AlexMAS commented Apr 15, 2024

Здравствуйте!

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

@IverCold
Copy link
Author

Я пробовал реализовать этот пример. Дело в том, что я отправляю открытый ключ в Контур, и они возвращают мне строку, которую я должен расшифровать с помощью закрытой части сертификата.
Это выглядит вот так:

            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.

В чём тут может быть проблема?

@AlexMAS
Copy link
Owner

AlexMAS commented Apr 16, 2024

Вам нужно внимательней посмотреть на указанный пример.

Метод DecryptKeyExchangeAlgorithm() делает дешифрацию общего секретного ключа, т.е. на вход он получает зашифрованный симметричный ключ. Как я понял, вы передаете ему не ключ, а зашифрованные данные. Для шифрации/дешифрации данных используется поток CryptoStream.

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

@IverCold
Copy link
Author

Я просто подумал, что есть вариант как-то выдернуть часть реализации расшифровки сообщения. Если я правильно понимаю, то речь идёт о расшифровке сообщения, зашифрованного открытым ключом сертификата. А значит его можно расшифровать закрытым ключом сертификата.
Подобно объекту RSACryptoServiceProvider, в котором есть методы .Encrypt(byte[]), .Decrypt(byte[]).

@AlexMAS
Copy link
Owner

AlexMAS commented Apr 18, 2024

Да, действительно, RSA имеет методы Encrypt()/Decrypt(). Однако примечательно, что его нет среди методов базового класса AsymmetricAlgorithm. Судя по коду RSACryptoServiceProvider, внутри вызываются методы EncryptKey()/DecryptKey(), что наводит на мысль, что под данными подразумевается все-таки ключ (симметричного) шифрования, а не сами данные. Вам действительно не передают зашифрованный симметричный ключ, только зашифрованные данные? Если так, то я попробую изучить тему глубже, может что-то и получится. :)

@AlexMAS
Copy link
Owner

AlexMAS commented Apr 23, 2024

@IverCold Если вопрос решен, предлагаю поделиться решением и закрыть задачу. :)

@IverCold
Copy link
Author

@AlexMAS Я лучше приложу инструкцию Контура, которую они мне дали. Нужно получить Access Token. Его можно получить по логину-паролю (как мы делаем сейчас), а можно по сертификату (так должно быть безопаснее). Чтобы получить токен по сертификату расшифровать случайный контент, который присылает Контур. Сам же инструкция вот здесь:
https://developer.testkontur.ru/doc/openidconnect?about=2

@IverCold
Copy link
Author

IverCold commented Apr 24, 2024

@IverCold Если вопрос решен, предлагаю поделиться решением и закрыть задачу. :)

Ну, я не настолько хорош, чтобы предложить решение в рамках вашей библиотеки = )
Но невероятная благодарность от меня за её существование. Без неё мы бы просто не взлетели - мы используем реализацию raw подписи для Контура/СФР как раз.

@AlexMAS
Copy link
Owner

AlexMAS commented Apr 24, 2024

Спасибо за обратную связь! :)

Понятно, то есть вам не удалось выполнить аутентификацию по сертификату. А можете прикрепить файл с base64 этого encrypted_key, я попробую посмотреть ее через ASN.1-редактор. Может что-то прояснится, что они присылают в ответ. :)

@AlexMAS
Copy link
Owner

AlexMAS commented Apr 29, 2024

@IverCold Здравствуйте! У вас нет примера encrypted_key? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants