2012-10-12 17 views
5

Sto tentando di utilizzare i certificati client per una connessione SSL utilizzando MonoTouch. Sembra che ci siano molti esempi per farlo usando l'obiettivo-c, e la soluzione che sto cercando sarebbe probabilmente simile a quella che ha risposto here ma in MonoTouch (C#).Certificati client HTTPS con Monotouch

Sto utilizzando la classe NSUrlConnection in MonoTouch e ho sovrascritto la classe NSUrlConnectionDelegate per rispondere alla richiesta di autenticazione.

Sono stato in grado di caricare i certificati dal file, ma non sono riuscito a trovare un'utile rappresentazione dei certificati per rispondere alla richiesta di autenticazione.

public override void ReceivedAuthenticationChallenge(NSUrlConnection connection, NSUrlAuthenticationChallenge challenge) 
{ 
    if (string.Equals(challenge.ProtectionSpace.AuthenticationMethod, "NSURLAuthenticationMethodClientCertificate", StringComparison.OrdinalIgnoreCase)) { 
     string password = "<password_signed_certificate>"; 
     byte[] data = File.ReadAllBytes("<path_of_file_in_ios_sandboxed_filesystem_pkcs>"); 
     NSDictionary opt = NSDictionary.FromObjectsAndKeys(new object[]{password}, new object[]{"passphrase"}); 
     NSDictionary[] items; 
     SecStatusCode stat = SecImportExport.ImportPkcs12(data, opt, out items); // Uses MonoTouch.Security namespace 
     MonoTouch.Security.SecTrust trust = (MonoTouch.Security.SecTrust)items[0]["trust"]; 
     // Everything to this point works, and I can inspect the trust object that all the expected certificate properties (IssuerName etc.) are correct 

     IntPtr secTrustRef = trust // ????? How do I bridge this gap 
     // NSUrlConnection does not utilise MonoTouch security namespace 

     NSUrlCredential cred = new NSUrlCredential(secTrustRef, true); 
     challenge.Sender.UseCredentials(cred, challenge); 
    } 
} 

Alcune note:

  1. ho visto le soluzioni Objective-C, ma non ho trovato l'insieme equivalente di passaggi necessari a MonoTouch (C#).
  2. Non riesco a utilizzare HttpWebRequest, poiché l'implementazione monotipo di httpWebRequest.ClientCertificates (una raccolta) genera un'eccezione non implementata.
  3. Ho anche tentato di utilizzare Mono.Security.X509 e System.Security.Cryptography.X509Certificates namespaces per aprire i certificati con esito positivo, ma ancora non riesco a utilizzare le istanze di classe per rispondere alla richiesta di autenticazione, poiché è necessario creare un oggetto NSUrlCredential che accetta solo un IntPtr.
  4. Vedere anche this.

risposta

1

Usa HttpWebRequest. Nel punto 2 delle domande, ho affermato che la proprietà HttpWebRequest.ClientCertificates genera un'eccezione non implementata e pertanto ho escluso questa opzione. Lo fa se provi a impostarlo come proprietà con una nuova raccolta, ma se utilizzi semplicemente la funzione di accesso Ottieni, puoi aggiungere un certificato client alla raccolta.

Come nota a margine, l'utilizzo di HttpWebRequest rende l'app più trasportabile su altri dispositivi, parte del motivo per cui utilizziamo MonoDevelop in modo da vincere.

+0

qualche idea su come farlo funzionare con NSUrlSession? – nhenrique

2

Non ho un ambiente server istituito per provare questo, ma provare questo:

Sostituire:

... 
MonoTouch.Security.SecTrust trust = (MonoTouch.Security.SecTrust)items[0]["trust"]; 
IntPtr secTrustRef = trust 
... 

con:

... 
NSObject obj = items[0]["trust"]; 
IntPtr secTrustRef = obj.Handle; 
... create and use your credentials 
GC.KeepAlive (obj); // just in case ;-) 
... 
+0

Grazie :) Questo mi ha superato il problema di come ottenere l'handle, e quindi la "risposta accettata". Purtroppo la richiesta non riesce ancora (anche se l'installazione del certificato come parte di un profilo su iPhone funziona con Safari connesso al sito). Non ho visto nessuno avere successo usando certificati MonoTouch e client. Spero solo che io stia facendo qualcosa di stupido, e non che semplicemente non sia possibile/non supportato. Continuerà a ricercare. Apprezzo l'assistenza. – Bruce