5

Desidero leggere i dettagli del certificato (ad esempio data di scadenza o CN) per motivi di sicurezza.Leggi dettagli certificato SSL su WP8

Di solito sono disponibili alcune proprietà nelle classi di rete che consentono di verificare il certificato. Questo manca nelle implementazioni del WP8.

Inoltre, ho provato a creare uno SslStream ma non c'è modo di ottenere dettagli del certificato come lo RemoteCertificate su .net 4.5.

var sslStream = new SslStream(new NetworkStream(e.ConnectSocket)); 

A SslStream manca tutto ciò che riguarda la sicurezza. Quindi sembra che anche BountyCastle e altre librerie non siano in grado di ottenere il certificato, perché il framework sottostante non lo supporta.

Quindi le mie domande sono:

  1. posso leggere il CN o altri Certificate dettagli su WP8 con altri approcci.?
  2. In caso contrario, come è possibile creare applicazioni seriamente sicure (line banking) su WP8 utilizzando tecniche come SSL Pinning o convalida del certificato lato client e c'è qualche ragione per cui questo non è supportato in WP8?

saluti Holger

risposta

1

Dopo aver provato librerie open source come BouncyCastle, SuperSocket o webSocket4net ho provato una valutazione di un lib commerciale di nome EldoS SecureBlackbox. Questo test ha avuto successo. Ecco un codice snipped, che ottiene i X509Certificates con tutti i dettagli:

public void OpenSSL() 
{ 
    var c = new TElSimpleSSLClient(); 
    c.OnCertificateValidate += new TSBCertificateValidateEvent(OnCertificateValidate); 

    c.Address = "myhostname.com"; 
    c.Port = 443; 
    c.Open(); 
    c.Close(false); 
} 

private void OnCertificateValidate(object sender, TElX509Certificate x509certificate, ref TSBBoolean validate) 
{ 
    validate = true; 
} 

La validazione è sempre tutti i certificati ... se convalidare è impostata su true, verrà mostrato il certificato successivo. Ciò significa che il callback è chiamato certificato forreach lì.

saluti Holger

0

Per WP8, è possibile utilizzare la classe StreamSocket, che ha un metodo UpgradeToSslAsync() che eseguirà l'handshake TLS come operazione asincrona. Una volta completato, è possibile utilizzare la proprietà .Information.ServerCertificate per verificare di avere ricevuto il certificato del server che si aspettava.

+0

proprietà StreamSocket.Information.ServerCertificate è stata aggiunta in Windows Phone 8.1! –

2

Su Windows Phone 8.1 questo può essere fatto con HttpClient, così come con StreamSocket (come suggerito da Mike).
L'esempio per la convalida del certificato con StreamSocket può essere trovato here (Scenario5_Certificato nel codice sorgente).

validazione certificato con HttpClient può essere fatta gestendo l'eccezione ERROR_INTERNET_INVALID_CA, convalidando il certificato server utilizzando la classe HttpTransportInformation, creando nuova istanza della classe HttpBaseProtocolFilter e specificando gli errori da ignorare.

Si noti che non tutti gli errori sono ignorabili.Riceverai un'eccezione se tenterai di aggiungere Success, Revocato, InvalidSignature, InvalidCertificateAuthorityPolicy, BasicConstraintsError, UnknownCriticalExtension o OtherErrors enum values.

che sto aggiungendo un codice di esempio che aggira gli errori del certificato utilizzando HttpClient:

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Threading.Tasks; 
using Windows.Security.Cryptography.Certificates; 
using Windows.Web.Http; 
using Windows.Web.Http.Filters; 

namespace Example.App 
{ 
    public class HttpsHandler 
    { 
     private const int ERROR_INTERNET_INVALID_CA = -2147012851; // 0x80072f0d 

     public static async void HttpsWithCertificateValidation() 
     { 
      Uri resourceUri; 
      if (!Uri.TryCreate("https://www.pcwebshop.co.uk/", UriKind.Absolute, out resourceUri)) 
       return; 

      IReadOnlyList<ChainValidationResult> serverErrors = await DoGet(null, resourceUri); 
      if (serverErrors != null) 
      { 
       HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter(); 
       foreach (ChainValidationResult value in serverErrors) 
       { 
        try { 
         filter.IgnorableServerCertificateErrors.Add(value); 
        } catch (Exception ex) { 
         // Note: the following values can't be ignorable: 
         //  Success Revoked InvalidSignature InvalidCertificateAuthorityPolicy 
         //  BasicConstraintsError UnknownCriticalExtension OtherErrors 
         Debug.WriteLine(value + " can't be ignorable"); 
        } 
       } 

       await DoGet(filter, resourceUri); 
      } 
     } 

     private static async Task<IReadOnlyList<ChainValidationResult>> DoGet(HttpBaseProtocolFilter filter, Uri resourceUri) 
     { 
      HttpClient httpClient; 
      if (filter != null) 
       httpClient = new HttpClient(filter); 
      else 
       httpClient = new HttpClient(); 

      HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, resourceUri); 
      bool hadCertificateException = false; 
      HttpResponseMessage response; 
      String responseBody; 

      try { 
       response = await httpClient.SendRequestAsync(requestMessage); 
       response.EnsureSuccessStatusCode(); 
       responseBody = await response.Content.ReadAsStringAsync(); 
      } catch (Exception ex) { 
       hadCertificateException = ex.HResult == ERROR_INTERNET_INVALID_CA; 
      } 

      return hadCertificateException ? requestMessage.TransportInformation.ServerCertificateErrors : null; 
     } 
    } 
} 
+2

Si prega di notare che questo funziona solo per Windows (Phone) 8.1 e non per WP 8.0. HttpRequestMessage non è supportato su WP 8.0. –

+0

@ReneSchulte modificato, grazie! –

Problemi correlati