Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline archimed7592  
#1 Оставлено : 12 ноября 2020 г. 15:15:51(UTC)
archimed7592

Статус: Участник

Группы: Участники
Зарегистрирован: 26.02.2014(UTC)
Сообщений: 26
Российская Федерация
Откуда: Москва

Поблагодарили: 4 раз в 4 постах
Здравствуйте.

Наткнулся на странное поведение AspNetCore.DataProtection - оно отличалось между .NET FW и .NET Core.
Подробное описание проблемы: .NET FW 4.8 DataProtection ProtectKeysWithCertificate with a certificate not stored in the certificate store.
Уже начал грешить на некорректную работу JIT и совершенно случайно локализовал проблему - она заключалася в установленном КриптоПро.NET.
AspNetCore.DataProtection имеет собственный класс EncryptedXmlWithCertificateKeys, который наследуется от EncryptedXml и переопределяет GetDecryptionKey для того, чтобы можно было расшифровывать ключ не только сертификатами из хранилища, но и вручную загруженным pfx из файла.
Так вот, штатно всё это работает, реализация базового класса дергает GetDecryptionKey и всё ОК.
А в случае с установленным КриптоПро.NET GetDecryptionKey не дергается и ничего не работает.
Есть ощущение, что КриптоПро.NET как-то подменяет штатную реализацию некоторых классов в .NET FW.

Можно ли с этим что-то сделать?
Offline Артём Макаров  
#2 Оставлено : 13 ноября 2020 г. 22:19:13(UTC)
Артём Макаров

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 20.02.2017(UTC)
Сообщений: 217

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 63 раз в 59 постах
Добрый день.

Пробуем воспроизвести ваш сценарий - всё отрабатывает на 4.8 с установленным КриптоПро.NET без ошибок на RSA сертификате.

Код:
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.DataProtection;

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            var dpp =
                DataProtectionProvider.Create(
                    keyDirectory:
                        new DirectoryInfo(
                            @"C:\tmp\DataProtectionTestKeyStore"),
                    setupAction:
                        cfg =>
                        {
                            cfg.ProtectKeysWithCertificate(
                                new X509Certificate2(
                                    fileName: @"C:\tmp\key.pfx",
                                    password: @"super-secret-password"));
                        });

            var dp = dpp.CreateProtector("test purpose");
            var secret = dp.Protect("test secret");
            Console.WriteLine(secret);
        }
    }
}


+ что интересно, не вижу в вашем стеке наших вызовов метода CPEncryptedXml.DecryptDocument, который мог бы всё сломать.
Код:
Unhandled Exception: System.Security.Cryptography.CryptographicException: Unable to retrieve the decryption key.
   at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument()
   at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.Decrypt(XElement encryptedElement)
   at Microsoft.AspNetCore.DataProtection.XmlEncryption.XmlEncryptionExtensions.DecryptElement(XElement element, IActivator activator)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.DeferredKey.<>c__DisplayClass1_0.<GetLazyDescriptorDelegate>b__0()
   at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.get_Value()
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyBase.get_Descriptor()
   at Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.CngGcmAuthenticatedEncryptorFactory.CreateEncryptorInstance(IKey key)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyBase.CreateEncryptor()
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRing.KeyHolder.GetEncryptorInstance(Boolean& isRevoked)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRing.get_DefaultAuthenticatedEncryptor()
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Protect(Byte[] plaintext)
   at Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.Protect(IDataProtector protector, String plaintext)
   at ConsoleApp9.Program.Main(String[] args)


Дабы воспроизвести максимально близко к вам - соберите пожалуйста проектик, на котором воспроизводится и приложите сертификат (желательно сам pfx + пароль, или хотя бы cer).
Укажите также используемую версию КриптоПро.NET (желательно, чтобы была последней).
И на всякий случай соберите и приложите osinfo.xml (подробнее - https://cpdn.cryptopro.r...ae-9898-f8cbc474e132.htm ):
Код:
cd C:\Program Files\Crypto Pro\.NET
alarm info

Отправить можно сюда архивом или на makarov@cryptopro.ru

Отредактировано пользователем 13 ноября 2020 г. 22:26:16(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline archimed7592  
#3 Оставлено : 16 ноября 2020 г. 9:04:51(UTC)
archimed7592

Статус: Участник

Группы: Участники
Зарегистрирован: 26.02.2014(UTC)
Сообщений: 26
Российская Федерация
Откуда: Москва

Поблагодарили: 4 раз в 4 постах
Добрый день.

Вот solution на котором я экспериментирую: sln
alarm info: osinfo
Версии на тестовой машине на которой экспериментировал (могу свободно удалять/устанавливать ПО):
* CSP 4.0.9975
* CPNet 1.0.7132.2

Версии на машине на которой изначально столкнулся с проблемой, но не могу удалить CP.NET:
* CSP 5.0.11944
* CPNet 1.0.7132.2

Отредактировано пользователем 16 ноября 2020 г. 9:05:39(UTC)  | Причина: Не указана

Offline archimed7592  
#4 Оставлено : 16 ноября 2020 г. 11:20:58(UTC)
archimed7592

Статус: Участник

Группы: Участники
Зарегистрирован: 26.02.2014(UTC)
Сообщений: 26
Российская Федерация
Откуда: Москва

Поблагодарили: 4 раз в 4 постах
Сделал пример, который вообще не использует DataProtection и демонстрирует проблему.

Код не требует ни pfx ни чего-либо ещё и содержит выжимку зашифрованного ключа из DataProtection.
.NET Core вариант кидает исключение "ОК", что подтверждает вход в переопредленный DecryptEncryptedKey.
.NET FW вариант кидает исключение Unhandled Exception: System.Security.Cryptography.CryptographicException: Unable to retrieve the decryption key. at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument(), т.е. до DecryptEncryptedKey дело не доходит.

Полный solution: CryptoProDotNetEncryptedXml
Сюда скопирую тело Main, чтобы можно было без скачивания оценить ситуацию.
Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace CryptoProDotNetEncryptedXml
{
    class Program
    {
        static void Main(string[] args)
        {
            var xml = @"
        <EncryptedData Type='http://www.w3.org/2001/04/xmlenc#Element' xmlns='http://www.w3.org/2001/04/xmlenc#'>
          <EncryptionMethod Algorithm='http://www.w3.org/2001/04/xmlenc#aes256-cbc' />
          <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
            <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
              <EncryptionMethod Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-1_5' />
              <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
                <X509Data>
                  <X509Certificate>MIIFOzCCAyOgAwIBAgIUNahT4sTQIh1TbBO2XM+X5B5w0g4wDQYJKoZIhvcNAQELBQAwJTEjMCEGA1UEAwwaRGF0YVByb3RlY3Rpb25UZXN0MjAyMDExMTAwHhcNMjAxMTEwMTg0NDI5WhcNMjAxMTExMTg0NDI5WjAlMSMwIQYDVQQDDBpEYXRhUHJvdGVjdGlvblRlc3QyMDIwMTExMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKJ/i1qszxcA3dguZ4q8d7BDYp05RAHn+keVyJleQhxK7O9Hy8tdIPxZOIwhUVYdds5UOMpke45z9JdnrOmlrge7hzSyKw+AXZYF7oJUgD9JZ08r1bTOW6bMBKfgW9u9ORwEh2Ge0cKEgsjL8JwqRqR71dy6MhyxnEmNf2MaoX0EOrgXjYplnFjHXhrl1lto5JwjW7gsLjam9j0uiRQp0K8uvgEYbu3hcHzVabmaJs0lqgiByUPxmOKIjkZezyPdZgYUpWoZZ/2w2OFSZGPyHF8X6Xb69bRWmpZp2d2cXvjrszJxwMFUzAHTPxdwUsQ4m0SLE+ix6OKcnn4Pdj4xj8SrxUJObSkN30nqna3BSWR/b5dfCpa8fh53wF5agFMZVHKjRp7Q1pMSQ40z4rOGs4N0cLk1tR/C6FZzePPH8KtjtPu7l4Fumt6kYHeATOV/zAt+D9NRMhMu0sn/KjwPY6lgWRqkO42B6CMPRZds7aOsgYPcI0+1oOqSJu0o6ktBSZfrTqipgdTjL4c+/GRef40OOidVFHJPjKxIuKJu/DUBVkOTJk0cot06ycF7hgl82Z3EQo8D2oiijlJz9n0+CdpXhKbTz50sX70IRt591fe/JpbdV8XE7ZEFUaikvcQgrUtOt/YkQgJ+OfFQYJdat1aUqyRoMlTECt84b6k/ZW3zAgMBAAGjYzBhMB0GA1UdDgQWBBTgQsl0/jVqoQPkovFx2cyek04/UTAfBgNVHSMEGDAWgBTgQsl0/jVqoQPkovFx2cyek04/UTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIE8DANBgkqhkiG9w0BAQsFAAOCAgEAkvK9N7hmpv7ui88QmJXO2LCXRtBJLVq9uT222rXAnq2lS3G4oKsvA6cXMaa0eds9MCMlHbZKjXWzolfQXTO9ByG7y4fjFmLBZ6z31QJXS4wzc92ILeJMYkKECqaXgW8qbGug0kX2d9ucAMC1C8QjH5jEC2c6bKOSsXFMZluQyBcuETzIkqJ7+TIPk4jxDMWyoJmKUV9R3Td8vPhztjIGSptvJxYsgypOkQv4XjJhvbi0GhlKZeQfjFnPeeZe7DVPIceoIbO/quTqZQsp5EBDqP2/C1gXROFumXgyKYmMhLPmieUTiQcFyomhA6lkcPWwEvgqVYeStaYUF1q15zjIKirSyRrbx9QKYEwVdmIShTt0A3Q3yz+CCxVXFMkS+YPlCWoKXfNwLx2vIctvJhAv2b3ABJkLnraxd8gShvpeQwchiZodOPz/EQB1f3qm4hJEmPNeZVRcgGsAWczQ0o9iLRB8Nw4I9K+m5Q7kohLopxROLA5MYSI/ESOH3d2SkfVyVQYhb9YBtVWgAk1SVBBIPVOujef3xE93Yy81dm4y3oGlEUwS8QatlRY+iIrFlijUIhq4buRkg26RQnmJ+nBFTB7s+qVOU+o8BmqQaUwgx3/qV1JeAPlhuWe3ou+r2/QzIvRcXsLQrpmo+bJZlCZ+rs5KFgj6yMbJE+cvhlK/8ew=</X509Certificate>
                </X509Data>
              </KeyInfo>
              <CipherData>
                <CipherValue>BCq00jehpyhkWRMv3MuTL9wueSUWXGjYMkJguiaLJ1z6f+k1rmB2xsR2FgsptdQU4whqA07PIw00Df7GWo77kizYtdndRWKB56HB9t/NA7PzmCM5WyP45m+oM1G/yPBrKqMBXjJEhcq4nVCS2EogMI5D1kB9UgTjrlP5JTVHt41dsDNfZKFnhHNJLq1qqr8aw40Oy1lC2QTz3yYoy/c9HonLaQDzlKivfmA1e9aJbaqqLuD0EWco1SCKFvrDE4+MsH5+yajSlMRe97KUev7TVpSHePDLSVFuMnAzMcFjUO+qZRHZL9RU5ubMyDWqSw9YPTSCRlvQOmFYhHrlWPDOhUHc5SBXMUX4lmF1OaZDyjGeO3afJYO73cgg2IQxXTiGGUi95G0xDp8gVUzhHk9+1rzYc+aBCL6IueZL1dzikC8s1t56vIgc9Ar4CHOYuW/788/A1gBelGvHR9bRFqpNsu+kN4svqHLTtm2kMEoOXsmaPtlT78HHlsaN06UQ+StRLnyKukCv3ZWGlHNf7z5Csv5C/RfvCICcApVn5HQP7Fup9OQK1SI5LfkwIzqQRs3MaBs+W2RltqpT8jGLYYpOZeLmzfsifIFhE8Mc6dB/YX+ZZJ+RA9Rovqx16FYFsgkDOaPLMg01jIoplmatURtww225Ks9Q6YPICYKPeb2mwvc=</CipherValue>
              </CipherData>
            </EncryptedKey>
          </KeyInfo>
          <CipherData>
            <CipherValue>AJp357+F98MEg04+IbtCM+mF0CvxPalEHya/SVK8PynDt4wW5xr9CKtYc3AWIqKgiikQGoxe1CFR4G6cKDQwV3lF0UvLEjJWjZSiMSTY+1jbEmnk8RTMfCjlu7/FdgnXNErmWBb0bdASTlaCCXmSA/qakgBkC0KpMmBbg9HKa6Z+5NE/S2Ipb5mxZgGhwWOc/tfTg9CB0fE8NEW8CP9u7RZ+j690CoFWk7Q46LyigMtqXNgN6XqjQ886uyhKFwmjX8auE48Cep9she7NUA3asJmKPRsNbraQOCvUaOeoTHOqoWp8gtk5sd7Q5ducUaTHzBUEV53PfrtKneS69hm9XduT0AvbBQXD5M5z7nH+Sv/wWir4HBtFJOUIEh2kKZZ9Es2CKb2abkbCqLCFjsNvyg==</CipherValue>
          </CipherData>
        </EncryptedData>";

            var xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(xml);

            var encryptedXml = 
                new EncryptedXml2(xmlDocument);

            encryptedXml.DecryptDocument();

        }
    }

    class EncryptedXml2
        : EncryptedXml
    {
        public EncryptedXml2(XmlDocument xmlDocument)
            : base(xmlDocument)
        { }

        public override byte[] DecryptEncryptedKey(EncryptedKey encryptedKey)
        {
            throw new Exception("OK");
        }
    }
}
Offline archimed7592  
#5 Оставлено : 16 ноября 2020 г. 11:24:09(UTC)
archimed7592

Статус: Участник

Группы: Участники
Зарегистрирован: 26.02.2014(UTC)
Сообщений: 26
Российская Федерация
Откуда: Москва

Поблагодарили: 4 раз в 4 постах
Автор: archimed7592 Перейти к цитате
AspNetCore.DataProtection имеет собственный класс EncryptedXmlWithCertificateKeys, который наследуется от EncryptedXml и переопределяет GetDecryptionKey для того, чтобы можно было расшифровывать ключ не только сертификатами из хранилища, но и вручную загруженным pfx из файла.
Так вот, штатно всё это работает, реализация базового класса дергает GetDecryptionKey и всё ОК.
А в случае с установленным КриптоПро.NET GetDecryptionKey не дергается и ничего не работает.



Прошу прощения, запутал вас. В DataProtection переопределен DecryptEncryptedKey и он как раз не дергается. А GetDecryptionKey я сам переопределял, когда пытался отладить проблему.
Offline Артём Макаров  
#6 Оставлено : 16 ноября 2020 г. 11:36:14(UTC)
Артём Макаров

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 20.02.2017(UTC)
Сообщений: 217

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 63 раз в 59 постах
Спасибо. Ошибку воспроизвели через DataProtection.

Проблема в том, что при использовании сборок core в .net Framework 4.8 используются и зависимости из core. Так как некоторые методы в core изменились, относительно 4.8 (в частности методы Security.Xml, в частности виновник вашей ошибки DecryptEncryptedKey) при их исправлении в КриптоПро.NET используется их старая логика (из .net Framework), которой видимо недостаточно для вашего сценария. В результате метод DecryptEncryptedKey возвращает null, ибо именно так повёл бы себя исправленный метод на .net Framework 4.8 в данном контексте.

Как лучше обойти данный момент - пока подумаем. Временно и экспериментально должна помочь правка реестра

Компьютер\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CProPatches\NetDetStarter40\XML

Добавьте строковый параметр HiVersion со значением 4.8. Сохраните и перезапустите машину. В результате исправления не должны устанавливаться на сборки Security.Xml версии 5.0

Snimok.PNG (22kb) загружен 4 раз(а).

Дополнение - не поможет. Отключит исправления на xml для 4.8. Ищем другое решение.

Отредактировано пользователем 16 ноября 2020 г. 12:06:33(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Артём Макаров  
#7 Оставлено : 16 ноября 2020 г. 12:05:46(UTC)
Артём Макаров

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 20.02.2017(UTC)
Сообщений: 217

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 63 раз в 59 постах
Нет, всё ещё обнаружилась проблема, при установке данного флага. Посмотрим дополнительно, что ещё можно сделать.
Техническую поддержку оказываем тут
Наша база знаний
Offline Артём Макаров  
#8 Оставлено : 17 ноября 2020 г. 10:07:07(UTC)
Артём Макаров

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 20.02.2017(UTC)
Сообщений: 217

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 63 раз в 59 постах
День добрый.

Внесли некоторые изменения для осуществления корректной работы вашего сценария. Для rsa сценария должен корректно вызываться перегруженный в наследниках метод. Тестовая сборка во вложении, пароль 1.

После обновления обязательна перезагрузка. Если по рекомендациям ранее создавали новое значение в реестре - его необходимо удалить.

NETSetup.zip (1,816kb) загружен 1 раз(а).
Техническую поддержку оказываем тут
Наша база знаний
Offline archimed7592  
#9 Оставлено : 17 ноября 2020 г. 15:12:47(UTC)
archimed7592

Статус: Участник

Группы: Участники
Зарегистрирован: 26.02.2014(UTC)
Сообщений: 26
Российская Федерация
Откуда: Москва

Поблагодарили: 4 раз в 4 постах
Тестовая сборка работает, спасибо!
Будет ли позднее боевая сборка или можно эту тестовую использовать в проде?
Offline Артём Макаров  
#10 Оставлено : 17 ноября 2020 г. 15:17:02(UTC)
Артём Макаров

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 20.02.2017(UTC)
Сообщений: 217

Сказал(а) «Спасибо»: 4 раз
Поблагодарили: 63 раз в 59 постах
Релиз будет позже, но с скорее всего с этой же правкой, если не обнаружим каких либо вылезших ошибок дополнительно.
Техническую поддержку оказываем тут
Наша база знаний
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.