使用Xamarin iOS进行客户端证书身份验证

时间:2015-10-10 06:53:20

标签: ios ssl xamarin xamarin.ios client-certificates

我已成功使用.Net HttpWebRequest课程成功使用客户端证书,但我现在正尝试更新ModernHttpClient以支持客户端证书,以便它可以使用请求的效率更高的iOS库。

我修改了DidReceiveChallenge中的NSUrlSessionHandler功能,以检查ClientCertificate的挑战,并尝试按照https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/AuthenticationChallenges.html上的信息进行操作,并将其转换为与Xamarin iOS配合使用。代码正确编译并逐步执行它会导致没有错误打印出来,但最终我仍然会收到System.Net.WebException抛出的消息'服务器" xxx.example.com"需要客户证书'。

我的代码如下......

public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
{
    ...snip... 

    if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodClientCertificate)
    {
        Console.WriteLine("Client Cert!");

        var password = "xxxxx";
        var options = NSDictionary.FromObjectAndKey(NSObject.FromObject(password), SecImportExport.Passphrase);

        var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Content", "client.p12");
        var certData = File.ReadAllBytes(path);

        NSDictionary[] importResult;

        X509Certificate cert = new X509Certificate(certData, password);

        SecStatusCode statusCode = SecImportExport.ImportPkcs12(certData, options, out importResult);
        var identityHandle = importResult[0][SecImportExport.Identity];
        var identity = new SecIdentity(identityHandle.ClassHandle);
        var certificate = new SecCertificate(cert.GetRawCertData());

        SecCertificate[] certificates = { certificate };
        NSUrlCredential credential = NSUrlCredential.FromIdentityCertificatesPersistance(identity, certificates, NSUrlCredentialPersistence.ForSession);
        completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);

        return;
    }

    ...snip...
}

如果你想试用它(https://github.com/MrsKensington/ModernHttpClient),我已经将我的更改提交给了GitHub。顺便说一句,测试客户端证书安全的Web服务器绝对没有任何价值(只有一个.txt文件),并且证书和密码对于这个Web服务器是唯一的,所以我毫不犹豫地与全世界分享这个。

提前感谢您的帮助,

肯辛顿夫人

1 个答案:

答案 0 :(得分:1)

你不应该使用句柄而不是句柄吗?

var identity = new SecIdentity(identityHandle.Handle);

到目前为止你有进展吗?我需要类似的WkWebView应用程序代码。