2010-06-23 68 views
7

向远程Web服务器发出HTTPS请求时,我使用WebRequest,它建立与远程Web服务器的安全连接。在开发过程中,我使用服务器上的自签名证书,并且WebRequest无法建立安全连接,因为证书无效,这是预期的行为。在HTTPS请求期间验证远程SSL证书

我发现此代码“远程”证书检查,通过在以下代码中调用SetCertificatePolicy()方法来激活。

public static void SetCertificatePolicy() 
{ 
    ServicePointManager.ServerCertificateValidationCallback 
       += RemoteCertificateValidate; 
} 

/// <summary> 
/// Remotes the certificate validate. 
/// </summary> 
private static bool RemoteCertificateValidate(
    object sender, X509Certificate cert, 
    X509Chain chain, SslPolicyErrors error) 
{ 
    // trust any certificate!!! 
    System.Console.WriteLine("Warning, trust any certificate"); 
    return true; 
} 

我想知道,如果它是可以做到远程SSL证书专项检查(使用上面的代码,例如),这样我就可以验证远程Web服务器使用有效的SSL证书,而不是任何有效的证书,但恰恰是我想要的证书?例如,我想确保我正在与www.someplace.com网站交谈,向ACME公司颁发证书,指纹00:11:22:.....

什么是“最佳实践“这种情况下的方法?

谢谢!

回答

7

如果您确实想要将其指定为一个特定的证书,您可以将证书数据(DER格式)与certificate.GetRawCertData()中的byte[]进行比较。

您还可以使用GetCertHashString()SubjectRemoteCertificateValidate中的certificate参数进行获取。主机名称应该在证书的主题备选名称中,或者如果主题(专有名称)的CN中没有主题备选名称。考虑到.NET格式化主题字符串的方式,这应该是您在那里找到的第一个CN =。

如果certificateX509Certificate2的实例,那么您还将获得更多数据。然后,您将能够获得SubjectName作为X500PrincipalName以及Extensions(以检查主题替代名称扩展名)。使用诸如BouncyCastle之类的工具来解析主题名称可能很有用。

根据运行时类型的不同,您也可能会获得更多有关您尝试联系sender中的主机名的信息。

+0

谢谢,那正是我所寻找的信息。关于第一个提示(比较证书数据与byte []),我需要比较已知的有效证书的字节数组和我正在验证的字节数组吗? – 2010-06-23 16:53:07

+0

我认为字节数组将会是DER编码中的证书,因此您应该将其与DER格式的参考证书(许多工具,包括Windows证书工具可以导出为该格式)进行比较。你甚至可以直接从证书库中加载(不知道如何)。 – Bruno 2010-06-23 17:29:28