Как именно строится цепочка сертификатов?

Как говорится в заголовке, я хочу знать, как строится цепочка сертификатов внутри.

У меня есть самозаверяющий корневой сертификат (CA) и сертификат входящего пользователя, который предположительно был подписан моим корнем, и это то, что я должен проверить. Тестирование X509Certificate2 можно выполнить с помощью метода X509Certificate2.Verify(), который использует X509Chain с некоторыми стандартными настройками. Чтобы иметь полный контроль над процессом, я использую X509Chain напрямую. Поскольку мой корень не установлен на машине (не в хранилище доверенных корневых сертификатов), я добавляю его в ExtraStore ChainPolicy.

Вся магия происходит в методе X509Chain.Build(), где я передаю свой пользовательский сертификат для проверки. Цепочка строится, начиная с переданного сертификата и заканчивая самоподписанным корнем. Но как именно? Как проверить, был ли сертификат подписан тем или иным корнем? Использует ли он цифровые подписи внутри?

Я попытался отладить все это, но остановился на импорте DLL, который использует метод CertGetCertificateChain из Libraries.Crypt32. Это материал C++, который выходит за рамки моих знаний.

Упрощенный код до сих пор:

      using (var chain = new X509Chain
            {
                ChainPolicy =
                {
                    RevocationMode = X509RevocationMode.NoCheck,
                    RevocationFlag = X509RevocationFlag.ExcludeRoot,
                    VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority,
                    VerificationTime = DateTime.Now,
                    UrlRetrievalTimeout = new TimeSpan(0, 0, 0)
                }
            })
            {
                chain.ChainPolicy.ExtraStore.Add(authority);

                if (!chain.Build(signedCertificate))
                {
                    //Errorhandling
                }

                //Root certificate should always be last in the X509ChainElements collection
                var isSignedByCorrectRootCert =
                    chain.ChainElements
                        .Cast<X509ChainElement>()
                        .Last()
                        .Certificate.Thumbprint == authority.Thumbprint;

                if (!isSignedByCorrectRootCert)
                {
                    //Errorhandling
                }
            }

1 ответ

Использует ли он цифровые подписи внутри?

в яблочко.

Я попытался отладить все это, но закончил импортом DLL, который использует метод CertGetCertificateChain из Libraries.Crypt32.

да, .NET X509Chainclass является не чем иным, как простой оболочкой собственных (C++) функций CryptoAPI. Я бы сказал, что более 95% криптографии в .NET являются оболочками над функциями CryptoAPI.

Много лет назад я написал сообщение в блоге, в котором объясняется, как выполняется построение цепочки в Microsoft Windows: Механизм цепочки сертификатов — как это работает . В этом посте объясняется, как механизм цепочки строит цепочку и привязывает сертификаты в цепочке перед отправкой ее в процедуру проверки. Проверка цепочки — гораздо более сложный процесс. Логика проверки описана в RFC 5280, §6.

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