我有一个连接到网络服务器的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;
}
}
}
答案 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 post,ExchangeAlgorithmType
可能是44550,相当于椭圆曲线Diffie-Hellman。椭圆曲线Diffie-Hellman确实支持完全前向保密。
如果您想修改当前代码以在一个连接中完成所有这些操作,则sslStream.RemoteCertificate
可以使用远程证书,因此您可以获得证书到期日期。
[1] 有可能并非所有Diffie-Hellman交换都支持Perfect Forward Secrecy。再次,考虑一下这种安全问题。