Ошибка проверки цифровой подписи с использованием Mimekit

Мы пытаемся использовать MimeKit для проверки цифровой подписи электронной почты (.p7m). Когда я звоню signature.Verify();, он выдает сообщение об ошибке:

{"Не удалось проверить цифровую подпись: требуется непустой набор\r\nИмя параметра: значение"}.

Но эта же почта была успешно проверена Limilabs.Mail.

Я использую приведенный ниже код для проверки подписи.

if (message.Body is MultipartSigned)
{
    var signed = (MultipartSigned)message.Body;
    foreach (var signature in signed.Verify())
    {
        try
        {
            bool valid = signature.Verify();

            // If valid is true, then it signifies that the signed content
            // has not been modified since this particular signer signed the
            // content.
            // However, if it is false, then it indicates that the signed
            // content has been modified.
        }
        catch (DigitalSignatureVerifyException)
        {
            // There was an error verifying the signature.
        }
    }
}

Может ли кто-нибудь помочь мне в этом, почему я получаю сообщение об ошибке?


person kiran p    schedule 02.12.2019    source источник
comment
С безопасностью есть много вариантов. У вас может возникнуть проблема с режимом шифрования 32 или 64 бита. См. : en.wikipedia.org/wiki/Transport_Layer_Security   -  person jdweng    schedule 02.12.2019
comment
Исключение — это нечто большее, чем просто свойство Message. Каков тип исключения? Что такое StackTrace? Что такое тип/сообщение/трассировка стека InnerException?   -  person jstedfast    schedule 02.12.2019
comment
Какой тип SecureMimeContext вы зарегистрировали по умолчанию? WindowsSecureMimeContext? Или это DefaultSecureMimeContext? Или что-то другое?   -  person jstedfast    schedule 02.12.2019
comment
Я получаю DigitalSignatureVerifyException, а внутренним исключением является System.ArgumentException. Внутреннее сообщение об исключении не является пустым. Требуется установить\r\nИмя параметра: значение   -  person kiran p    schedule 03.12.2019
comment
трассировка стека -- в Org.BouncyCastle.Pkix.PkixParameters.SetTrustAnchors(ISet tas) в Org.BouncyCastle.Pkix.PkixParameters..ctor(ISet trustAnchors) в Org.BouncyCastle.Pkix.PkixBuilderParameters..ctor(ISet trustAnchors, IX509Selector targetConstraints ) в MimeKit.Cryptography.BouncyCastleSecureMimeContext.BuildCertPath(якоря HashSet, сертификаты IX509Store, IX509Store crls, сертификат X509Certificate, DateTime signingTime) в MimeKit.Cryptography.BouncyCastleSecureMimeContext.‹GetDigitalSignaturesAsync›d__29().MoveNext().   -  person kiran p    schedule 03.12.2019
comment
Импортировали ли вы какие-либо якоря доверия в свой SecureMimeContext? Это похоже на проблему. MimeKit не поставляется с какими-либо корневыми сертификатами CA, поэтому для начала у него будет 0 якорей доверия. Вам нужно импортировать некоторые из них или использовать другой SecureMimeContext по умолчанию (например, WindowsSecureMimeContext, если вы работаете в .NETFramework в Windows).   -  person jstedfast    schedule 03.12.2019
comment
CryptographyContext.Register (typeof (WindowsSecureMimeContext));   -  person jstedfast    schedule 03.12.2019


Ответы (1)


Проблема здесь в том, что MimeKit по умолчанию использует бэкенд DefaultSecureMimeContext для S/MIME, когда разработчик явно не предоставил контекст для использования в вызове метода MultipartSigned.Verify(), а также не зарегистрировал альтернативный контекст S/MIME с использованием CryptographyContext.Register().

Поскольку DefaultSecureMimeContext начинается с пустой базы данных сертификатов S/MIME, у него нет доверенных якорей (также называемых сертификатами корневого центра сертификации) и, таким образом, выдается исключение, которое вы видите, когда он идет для создания цепочки сертификатов для подписавшего S/MIME, когда проверка подписи.

Вы можете исправить это, либо импортировав несколько сертификатов корневого центра сертификации (предпочтительно включая тот, который необходим для построения цепочки сертификатов для указанного подписывающего лица), либо с помощью WindowsSecureMimeContext:

if (message.Body is MultipartSigned)
{
    var signed = (MultipartSigned)message.Body;

    using (var ctx = new WindowsSecureMimeContext ()) {
        foreach (var signature in signed.Verify(ctx))
        {
            try
            {
                bool valid = signature.Verify();

                // If valid is true, then it signifies that the signed content
                // has not been modified since this particular signer signed the
                // content.
                // However, if it is false, then it indicates that the signed
                // content has been modified.
            }
            catch (DigitalSignatureVerifyException)
            {
                // There was an error verifying the signature.
            }
        }
    }
}
person jstedfast    schedule 03.12.2019
comment
Привет jstedfast, Спасибо за ответ. Он отлично работает после добавления WindowsSecureMimeContext. - person kiran p; 10.12.2019
comment
Рад, что это сработало для вас. Не могли бы вы нажать, чтобы принять мой ответ? Это поможет другим пользователям увидеть, что решение работает, не читая комментарии. Спасибо! - person jstedfast; 10.12.2019