证书链究竟是如何构建的?

How exactly is a Certificate chain built?

如标题所述,我想知道内部证书链是如何构建的。

我有一个自签名的根证书 (CA) 和一个传入的用户证书,据推测这是由我的根签名的,这是我必须测试的。可以使用 X509Certificate2.Verify() 方法测试 X509Certificate2,该方法使用具有一些标准设置的 X509Chain。为了完全控制我直接使用 X509Chain 的过程。由于我的根没有安装在机器上(不在受信任的根证书存储中),我将它添加到 ChainPolicy 的 ExtraStore。

整个魔法都发生在 X509Chain.Build() 方法中,我在其中传递我的 'to be tested' 用户证书。链得到构建,从通过的证书开始,到自签名根结束。但究竟如何呢?如何测试证书是否已由一个或另一个根签名?它在内部使用数字签名吗?

我尝试调试整个过程,但以 DLL 导入结束,它使用 Libraries.Crypt32 中的 CertGetCertificateChain 方法。那是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
                }
            }

Does it use digital signatures internally?

完全正确。

I tried to debug the whole thing but ended at an DLL import, which uses the CertGetCertificateChain method from Libraries.Crypt32.

是的,.NET X509Chain class 只不过是对 CryptoAPI 本机 (C++) 函数的简单包装。我会说 .NET 中 95% 以上的密码学内容都是 CryptoAPI 函数的包装器。

几年前,我写了一篇博客 post,解释了如何在 Microsoft Windows 中执行链构建:Certificate Chaining Engine — how it works. This post explains how chaining engine builds the chain and bind certificates in the chain before sending it to validation routine. Chain validation is a much more complex process. Validation logic is described in RFC 5280, §6