2015-01-02 7 views
5

Ho un programma C# che si collega a un server web e visualizza la data di scadenza del certificato SSL.Come determinare se una connessione a un server Web utilizza Perfect Forward Secrecy?

Quello che vorrei sapere è come determinare se la connessione utilizza 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; 
     } 
    } 
} 

risposta

6

Prefazione: non sono un crittografo.

Per this Information Security risposta, si desidera esaminare la suite di crittografia concordata, vale a dire il pezzo chiave di scambio della suite. In base a ciò, qualsiasi cosa basata su Diffie-Hellman fornisce un perfetto segreto in avanti. Come sottolinea erickson nei commenti, questo potrebbe essere falso e vorrai capire le complicazioni della sicurezza nell'assumere che Perfect Forward Secrecy sia presente quando in realtà non lo è.

Con quello, stai cercando SslStream. Ciò ti consentirà di accedere alle proprietà di scambio delle chiavi di cui hai bisogno.

Non è così facile come usare uno WebRequest o anche uno HttpRequest. Dovrai scrivere tu stesso la connessione. Un esempio è il seguente:

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 
} 

In teoria, KeyExchangeAlgorithm è un'enumerazione. E potresti fare if(sslStream.KeyExchangeAlgorithm == ExchangeAlgorithmType.DiffieHellman) e saprai la risposta [1]. Ma secondo this Microsoft Forum post, ExchangeAlgorithmType può essere 44550 che è equivalente alla curva ellittica Diffie-Hellman. Curva ellittica Diffie-Hellman supporta Perfect Forward Secrecy.

Se si desidera modificare il codice corrente per fare in modo che tutto ciò avvenga in un'unica connessione, il certificato remoto è disponibile allo sslStream.RemoteCertificate in modo da poter ottenere la data di scadenza del certificato.

[1] È possibile che non tutte le borse Diffie-Hellman supportino Perfect Forward Secrecy. Ancora una volta, considera le complicazioni di sicurezza di questo.

+0

Avrei dovuto leggere, ma credo che ci siano modalità DH che * non * forniscono PFS. Penso che tu abbia bisogno di guardare in modo più specifico per * accordo chiave DH * effimero (suite di crittografia EDH_XXX). – erickson

+1

Cerca DHE (EDH; Diffie-Hellman effimero) ed ECDHE (EECDH; Curva ellittica Diffie-Hellman effimero). Solo questi algoritmi di accordo chiave forniscono PFS. DH, ECDH e RSA no. – zakjan

+0

Steven, ho ragione nella mia comprensione che stai dicendo che se si crea una connessione usando WebRequest.Create, allora non c'è modo di determinare quale tipo di crittografia viene utilizzata? – JonnyBoats

Problemi correlati