SignedCms.CheckSignature () всегда терпит неудачу при использовании действительного сертификата - PullRequest
1 голос
/ 30 января 2020

Я пытаюсь использовать SignedCms.CheckSignature in. NET Framework 4.7.2 для проверки сообщения, которое, как я знаю, действительно, с использованием сертификата, который, как я знаю, действителен. Для этого я использую следующий код:

    using System.Security.Cryptography.Pkcs;
    using System.Security.Cryptography.X509Certificates;
    using System.Collections.Generic;

    public class VerifySignature {

        public static void Main(string [] args) {
            byte[] signature = FromHexString(secKey);
            byte[] certBytes = FromHexString(sCert);
            var certificate = new X509Certificate2(certBytes);
            var collection = new X509Certificate2Collection(certificate);
            var verifyCms = new SignedCms();
            verifyCms.Decode(signature);
            verifyCms.CheckSignature(collection, true);
        }

        // Disposable certificate + secKey
        private const string sCert = @"3082045406092A864886F70D010702A082044530820441020101310B300906052B0E03021A0500300B06092A864886F70D010701A08202FF308202FB308202BB020720110818132047300906072A8648CE3804033064310B3009060355040613024445311C301A060355040A131353415020547275737420436F6D6D756E69747931133011060355040B130A5341502057656220415331143012060355040B130B4930313230303033343131310C300A06035504031303494433301E170D3131303831383133323034375A170D3338303130313030303030315A3064310B3009060355040613024445311C301A060355040A131353415020547275737420436F6D6D756E69747931133011060355040B130A5341502057656220415331143012060355040B130B4930313230303033343131310C300A06035504031303494433308201B73082012C06072A8648CE3804013082011F02818100FFF96C9CDD661022E93DF5B27DB6C6C9FF34358366D2C7C3C37838703E4A4876429227017338D65A73617D5640C6764C67B2E5BE771F4937C6AC43E96780A57CA64C47ADE6C6D0336E5CA39D77035EA1F836A45CA1C0255D7AC473C9C9B09E40C07D2AC3B0C72F27273AA9F0B0221CB484A5A3E565D3540531A170E7E9ACFD4302150095C9AE5339A3D29AAA7A3705C884166335740DD302818100F808A1CE9A4C20F2FA4470BD5D9AAA4E69E18E5F5F182272770050B86EFD750011EBF938ADA9F63E6956F533E2B829C28A407A2D5735F41E020E36D1CBA8092000C597BE2A6022AED8BC95C720CE8465EAD415B19F1560964EC0422A9A5C9DADDC373AAF8F90AB6E6248A74F3A51EF4A5E06346FE3270449E7E8B2E88178450E038184000281806A7DE80E4DAAE5CB95DC79D7C3C2B15EDE1973453E09AF4EBDCDFF55ADA9256C0FC4E98EE443D5916D9CB6C54BD7D9612A02693BEF866BE4C4777E159121EE285A6199FF30AF309E675B4E1ADAE95E4A5254CBC37C49C77EC9A3169B5BDA1D7FFB24C27334B7A0E3E6FBEC4257C0C1C3F6CDAE5D3F8748F52607B399BCF0A61C300906072A8648CE380403032F00302C02144AC6E9813C2F7EFEEFED0A9FE60E4816DA964B9F02145327E3FE9FA347864ABCCC0198E519AEEE678C7E3182011D30820119020101306F3064310B3009060355040613024445311C301A060355040A131353415020547275737420436F6D6D756E69747931133011060355040B130A5341502057656220415331143012060355040B130B4930313230303033343131310C300A06035504031303494433020720110818132047300906052B0E03021A0500A05D301806092A864886F70D010903310B06092A864886F70D010701301C06092A864886F70D010905310F170D3230303132393139343630355A302306092A864886F70D01090431160414B858CB282617FB0956D960215C8E84D1CCF909C6300906072A8648CE380403042E302C02143DED3FA580EF178F0190EB66033EF0E2FFD647CC02146857D6E9123802BC9589D3B7D52BB8A11C348081";
        private const string secKey = @"3082015106092A864886F70D010702A08201423082013E020101310B300906052B0E03021A0500300B06092A864886F70D0107013182011D30820119020101306F3064310B3009060355040613024445311C301A060355040A131353415020547275737420436F6D6D756E69747931133011060355040B130A5341502057656220415331143012060355040B130B4930313230303033343131310C300A06035504031303494433020720110818132047300906052B0E03021A0500A05D301806092A864886F70D010903310B06092A864886F70D010701301C06092A864886F70D010905310F170D3230303132393232323635385A302306092A864886F70D010904311604141A1A7B63F70EA93616A10297BA4D27FB9255753B300906072A8648CE380403042E302C0214323B9B50FAAD0823C14A6565B0CA291DBC0A967B0214511F586BFB544E63256CD49DA1FF03FF2984F640";

        private byte[] FromHexString(string hexString) {
            var bytes = new List<byte>();
            int by = 0;
            int hexDigits = 0;
            for (int i = 0; i < hexString.Length; ++i) {
                char c = hexString[i];
                if ('0' <= c && c <= '9') {
                    by = (by << 4) | (c - '0');
                    ++hexDigits;
                } else if ('A' <= c && c <= 'F') {
                    by = (by << 4) | (c - 'A' + 10);
                    ++hexDigits;
                }
                if (hexDigits == 2) {
                    bytes.Add((byte)by);
                    hexDigits = 0;
                }
            }
            return bytes.ToArray();
        }
    }

Я проверил, что X509Certificate2 является действительным, а secKey правильно декодирован. И все же, когда я звоню SignedCms.CheckSignature, я получаю исключение cryptographi c с сообщением «Значение ha sh неверно».

Мои ожидания, что этот код должен работать некорректно?

1 Ответ

2 голосов
/ 31 января 2020

Ваше значение CMS SignedData из secKey создается с отдельным контентом, то есть это просто подпись. То, как вы пытаетесь это проверить, это проверка того, что подпись применяется к new byte[0].

  • new byte[0] имеет SHA-1 га sh DA39A3EE5E6B4B0D3255BFEF95601890AFD80709
  • Подпись применяется к содержанию с SHA-1 га sh из 1A1A7B63F70EA93616A10297BA4D27FB9255753B
  • Исключение: значение ha sh неверно.

Вам необходимо найти содержимое и измените конструкцию вашего документа на

ContentInfo detachedData = new ContentInfo(data);
SignedCms verifyCms = new SignedCms(detachedData, detached: true);
// rest of code goes here.

Как только внутренний дайджест может быть проверен, подпись будет успешно проверена с использованием ключа publi c (на основании некоторых манипуляций с данными в отладчике).

...