Цифровая подпись XML действительна локально, но отклонена удаленным сервером при работе в контейнере Linux Docker (.NET C#

Место общения программистов C#
Ответить
Anonymous
 Цифровая подпись XML действительна локально, но отклонена удаленным сервером при работе в контейнере Linux Docker (.NET

Сообщение Anonymous »

У меня есть веб-API .NET 5, который создает запрос SOAP, подписывает его части с помощью цифровых подписей XML (RSA-SHA256, Exclusive C14N) и отправляет его в удаленную службу SOAP.
Запрос выполняется успешно в Windows (Visual Studio 2022, IIS Express), но не выполняется в Linux (контейнер Docker, та же среда выполнения .NET 5), при этом удаленный сервер отвечает: «alert-signature-not-valid».
Подпись XML проверяется локально на обеих платформах — дайджест совпадает, проверка RSA проходит. Но удаленный сервер принимает только запросы, исходящие от Windows.
ОКРУЖАЮЩАЯ СРЕДА:
-----------
- .NET 5.0 (с нацеленностью на net5.0)
- System.ServiceModel.Http (клиент WCF, CoreWCF-совместимый)
- System.Security.Cryptography.Xml для SignedXml
- Windows: Win10/11, RSACng, работает нормально
- Linux: Docker-контейнер Ubuntu 18.04, RSAOpenSsl, подпись отклонена
АРХИТЕКТУРА:
------------
Подписание + конвейер отправки:
Шаг 1. Подпишите XML-предупреждение с помощью SignedXml с помощью XmlDsigExcC14NTransform + rsa-sha256 (завернутая подпись со ссылочным URI="")
Шаг 2. WCF сериализует подписанное оповещение в конверт SOAP через XmlSerializer
Шаг 3: SigningMessageInspector.BeforeSendRequest перехватывает сообщение WCF, преобразует его в строку, добавляет wsu:Id к элементу Body, подписывает тело вторым эталонным URI="#bodyId", добавляет заголовок wsse:Security с BinarySecurityToken + Signature, затем создает новое сообщение из подписанной строки XML
Шаг 4: CustomEncoder.WriteMessage перехватывает сообщение, чтобы изменить порядок элементов XML (переместить подпись в wsse:Security), затем базовый TextMessageEncoder записывает последние байты.
ЧТО Я ПРОВЕРИЛ:
--------------------
1. Подписи действительны локально на обеих платформах
[CAP-Sign] ЛОКАЛЬНАЯ САМОВЕРИФИКАЦИЯ result=True
[CAP-Sign] ПЕРЕСЕРИАЛИЗОВАННАЯ ОБЩАЯ ПРОВЕРКА: дайджестОК=True, rsaOK=True, общий=True
[CAP-Sign] Дрейф не обнаружен. Предварительное подписание и повторная сериализация тела совпадают.
И Windows, и Linux создают локально действительные подписи как для тела оповещения, так и для тела SOAP.
2. Сертификат клиента mTLS отображается правильно в Linux
[mTLS-Probe] Подтверждение TLS в порядке. Protocol=Tls13, LocalCertPresented=CN=MyCert..., IsMutuallyAuthenticated=True
Сервер принимает соединение TLS. Проблема заключается в уровне SOAP/XML, а не в TLS.
3. Закрытый ключ сертификата работает на обеих платформах
[CertLoad] HasPrivateKey=True, RSAType=System.Security.Cryptography.RSAOpenSsl, KeySize=2048, CanSign=True
Выполнен повторный импорт PFX для совместимости с Linux OpenSSL. Ключ можно подписать.
4. Один и тот же сертификат, один и тот же отпечаток на обеих платформах.
Обе используют один и тот же сертификат X509 (один и тот же отпечаток, один и тот же серийный номер эмитента).
5. PreserveWhitespace=false и Exclusive C14N используются последовательно
var xdoc = new XmlDocument { PreserveWhitespace = false };
bodyRef.AddTransform(new XmlDsigExcC14NTransform());
CRLF и LF не являются проблемой — канонизация нормализует пробелы.
6. Никакого смещения XML после повторной сериализации
Хеши тела до и после подписи совпадают. XmlSerializer не изменяет XML после прикрепления подписи.
Кто-нибудь сталкивался с подобной проблемой, когда подписи SignedXml действительны локально, но отклоняются удаленным сервером только при работе в Linux (.NET 5+)? Что было исправлено?

Подробнее здесь: https://stackoverflow.com/questions/798 ... -running-i
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»