如何确定与Web服务器的连接是否正在使用Perfect Forward Secrecy?

时间:2015-01-02 11:28:45

标签: c# ssl https

我有一个连接到网络服务器的C#程序,并显示SSL证书的截止日期。

我想知道的是如何确定连接是否正在使用Perfect Forward Secrecy [PFS]?

using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ServicePointManager.ServerCertificateValidationCallback += ServerCertificateValidationCallback;
            ServicePointManager.CheckCertificateRevocationList = true;

            var request = WebRequest.Create("https://www.microsoft.com/");

            var response = request.GetResponse();

            Console.WriteLine("Done.");
            Console.ReadLine();
        }
        private static bool ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            Console.WriteLine("Certificate expires on " + certificate.GetExpirationDateString());

            return true;
        }
    }
}

1 个答案:

答案 0 :(得分:6)

前言:我不是密码学家。

this Information Security答案,您想要查看商定的密码套件,即套件的密钥交换件。据此,基于Diffie-Hellman的任何东西都提供了完美的前向保密。正如埃里克森在评论中指出的那样,这可能是不真实的,你会想要理解假设完美前瞻性保密的安全性并发症,当它真的不存在时。

有了这个,你正在寻找SslStream。这样您就可以访问所需的密钥交换属性。

这不像使用WebRequest甚至是HttpRequest那么容易。您自己必须写出连接。示例如下:

string host = "www.microsoft.com";

using (var client = new TcpClient(host, 443))
using (var stream = client.GetStream())
using (var sslStream = new SslStream(stream))
{
    sslStream.AuthenticateAsClient(host);

    // figure out if sslStream.KeyExchangeAlgorithm support PFS here
}

理论上,KeyExchangeAlgorithm是一个枚举。你可以做if(sslStream.KeyExchangeAlgorithm == ExchangeAlgorithmType.DiffieHellman),你就会知道答案 [1] 。但根据this Microsoft Forum postExchangeAlgorithmType可能是44550,相当于椭圆曲线Diffie-Hellman。椭圆曲线Diffie-Hellman确实支持完全前向保密。

如果您想修改当前代码以在一个连接中完成所有这些操作,则sslStream.RemoteCertificate可以使用远程证书,因此您可以获得证书到期日期。

[1] 有可能并非所有Diffie-Hellman交换都支持Perfect Forward Secrecy。再次,考虑一下这种安全问题。