SignedXml.CheckSignature() всегда ложно

Я получаю подписанный XML от третьей стороны с приложенным сертификатом. У меня также есть копия этого сертификата локально, чтобы убедиться, что серийные номера равны, что они есть, поэтому я уверен, что XML подписан тем же сертификатом, что и у меня локально.

Однако SignedXml.CheckSignature() всегда возвращает false, поэтому проверка всегда заканчивается неудачей. Это почему? Из того, что я понял, подписанный XML всегда включает в себя копию сертификата, которым он подписан, и метод без параметров пытается проверить подпись по этому сертификату. Разве это не должно всегда работать?

К вашему сведению: проверка подписи с помощью локальной копии сертификата также не выполняется в каждом случае.

РЕДАКТИРОВАТЬ 09 декабря 2016

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

Может ли проблема быть вызвана ссылкой с префиксом cid, как указано на https://blogs.msdn.microsoft.com/alejacma/2010/08/18/creating-signatures-with-signedxml-following-ebxml-standard/? Это довольно старая статья, с тех пор все могло измениться.

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/RECxml-c14n-20010315"></ds:CanonicalizationMethod>
        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
            <ds:Reference URI="">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#envelopedsignature"></ds:Transform>
                    <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:Transform>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
                    <ds:DigestValue>RJ2QdODr5ADUs9RAR9aT8NFdqds=</ds:DigestValue>
            </ds:Reference>
            <ds:Reference URI="cid:ebxhmpayload111@example.com">
                <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
                    <ds:DigestValue>j1BG/SCN4Z74inL530u2SYGWKtE=</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
    <ds:SignatureValue>ZRLxNWAWqxvW1d9vdtZhQ3cII02NhUk7H8ugAML0cIrP0noebUMikAOuX6fNIVTvi4kLAeb3FfQqBJD6heRWrM0lMZsA0rIHVOtH3fc6JqwUWRuiS9zzuKIx5ah8O0yU1ZkeS5b6fTJtX36+idO5KvTZc2az7fpWhPLcrfcyT4A=
    </ds:SignatureValue>
    <ds:KeyInfo>
        <ds:X509Data>
            <ds:X509Certificate>*redacted*</ds:X509Certificate>
        </ds:X509Data>
    </ds:KeyInfo>
</ds:Signature>

Код:

        var xmlDoc = new XmlDocument();
        xmlDoc.PreserveWhitespace = false;
        xmlDoc.LoadXml(xmlData);
        var signedXmlDoc = new SignedXml(xmlDoc);
        var signatureNodeList = xmlDoc.GetElementsByTagName("Signature");
        signedXmlDoc.LoadXml((XmlElement)signatureNodeList[0]);
        var signingCertificate = new X509Certificate2(sender.SigningCertificate);
        foreach (var ex in signingCertificate.Extensions)
        {
            if (ex.Oid.Value == "2.5.29.15")
            {
                var ext = (X509KeyUsageExtension)ex;
                if (!ext.KeyUsages.HasFlag(X509KeyUsageFlags.NonRepudiation))
                    throw new CertificateException("The signing certificate does not support non-repudiation.");
            }
        }

        var transmittedCert = new X509Certificate2(Convert.FromBase64String(xmlDoc.GetElementsByTagName("X509Certificate")[0].InnerText));
        if (transmittedCert.SerialNumber != signingCertificate.SerialNumber)
            throw new CertificateException("Serial numbers do not match. The message was signed by another certificate");

        var validSignature = signedXmlDoc.CheckSignature();

0 ответов

Другие вопросы по тегам