.Net编程:在SSL自签名证书上验证什么

.Net编程:在SSL自签名证书上验证什么,.net,ssl-certificate,.net,Ssl Certificate,我无法让用户为他们的服务器创建真正的证书,但我想做一些安全检查。所以下面的内容太浅显了,因为正如我读到的,没有检查证书 ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 您建议我如何让客户检查x509证书?鉴于我使用的是.NET语言(c#/f#)。如果您无法让客户端创建真正的证书,您至少应该尝试让他们使用您的服务器创建证书。然后,您可以检查证书是否有效,或者至少从您的CA检查

我无法让用户为他们的服务器创建真正的证书,但我想做一些安全检查。所以下面的内容太浅显了,因为正如我读到的,没有检查证书

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

您建议我如何让客户检查x509证书?鉴于我使用的是.NET语言(c#/f#)。

如果您无法让客户端创建真正的证书,您至少应该尝试让他们使用您的服务器创建证书。然后,您可以检查证书是否有效,或者至少从您的CA检查证书是否有效,因为您将知道您的CA是否已被泄露。如果您信任任何和所有CA,那么实际上没有什么值得检查的。

如果您使用的是自签名证书,那么您应该预期的唯一错误是根证书(证书颁发者)上的链错误。我建议这样做,专门捕捉链式错误,并让所有其他错误通过

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(
    ValidateRemoteCertificate
);

private static bool ValidateRemoteCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors )
{
    string trustedIssuer = "CN=www.domain.com";
    string trustedDomain = "CN=www.domain.com";
    bool policyErr = false;

    switch (policyErrors)
    {
        case SslPolicyErrors.None:
            policyErr |= false;
            break;
        case SslPolicyErrors.RemoteCertificateChainErrors:
            bool chainErr = false;
            foreach (X509ChainStatus status in chain.ChainStatus)
            {
                switch (status.Status)
                {
                    case X509ChainStatusFlags.NoError:
                        chainErr |= false;
                        break;
                    case X509ChainStatusFlags.UntrustedRoot:
                        if (certificate.Subject != trustedDomain || certificate.Issuer != trustedIssuer)
                            chainErr |= true;
                        else
                            chainErr |= false;
                        break;
                    default:
                        chainErr |= true;
                        break;
                }                    
            }
            policyErr |= chainErr;
            break;
        default:
            policyErr |= true;
            break;
    }

    return !policyErr;
}

如果您可以检查证书,您可以将自己的验证逻辑放在函数ValidateRemoteCertificate中

System.Net.ServicePointManager.ServerCertificateValidationCallback += (a, b, c, d) =>
{
     return ValidateRemoteCertificate(a, b, c, d);
};

private static bool ValidateRemoteCertificate(object sender, X509Certificate certificate,
            X509Chain chain, SslPolicyErrors policyErrors)
{
            if (certificate.Subject.Equals("CN=www.domain.com"))
                return true;
            else
               return policyErrors == SslPolicyErrors.None; 

}

+我完全同意。除非您可以信任颁发证书的CA,否则证书的其余部分几乎毫无意义。如果你不能使用真正的证书,那么正如斯宾塞所说,看看你是否可以建立(或已经拥有)你自己的CA,你可以信任它,并从那里向你的用户颁发证书。是的,这是一个糟糕的情况,但我正试图让它不那么糟糕。至少我会检查证书中的名称是否与给定的URL匹配。请不要这样做。这比什么都没有更糟糕,因为它提供了安全的假象,但却没有。任何人都可以创建一个包含字符串“CN=www.domain.com”的证书。