Ssl NSUrlSession:仅当还需要客户端证书时,质询NSURAuthenticationMethodServerTrust才会失败
我们希望将应用程序连接到IIS Web服务。我们使用自签名证书和客户端证书进行身份验证 当webservice不需要客户端证书身份验证时,一切正常,调用nsurAuthenticationMethodServerTrust并继续请求。 但是,当我在服务器上激活客户端证书身份验证时,在使用NSURLAuthenticationMethodServerTrust作为质询的DidReceiveChallenge之后,会调用DidCompleteWithError。错误消息是:“此服务器的证书无效。您可能正在连接假装为“192.168.221.118”的服务器,这可能会使您的机密信息处于危险之中 注意:“NSURLAuthenticationMethodClientCertificate”从未被调用,应用程序在此之前崩溃。 客户端证书由中间证书签名,因此我不理解ServerTrust质询失败的原因 另外:在我看来,这是不必要的,但我也尝试将客户证书添加到Sectrust的AnchorCertificates集合中 提前感谢你的帮助 这是我的密码:Ssl NSUrlSession:仅当还需要客户端证书时,质询NSURAuthenticationMethodServerTrust才会失败,ssl,xamarin.ios,nsurlsession,nsurlsessiondatatask,Ssl,Xamarin.ios,Nsurlsession,Nsurlsessiondatatask,我们希望将应用程序连接到IIS Web服务。我们使用自签名证书和客户端证书进行身份验证 当webservice不需要客户端证书身份验证时,一切正常,调用nsurAuthenticationMethodServerTrust并继续请求。 但是,当我在服务器上激活客户端证书身份验证时,在使用NSURLAuthenticationMethodServerTrust作为质询的DidReceiveChallenge之后,会调用DidCompleteWithError。错误消息是:“此服务器的证书无效。您可
private class SessionDelegate : NSUrlSessionDataDelegate, INSUrlSessionDelegate
{
private Action<bool, string> completed_callback;
private string antwortCache;
private int status_code;
public SessionDelegate(Action<bool, string> completed)
{
completed_callback = completed;
antwortCache = "";
}
public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
{
if (challenge.PreviousFailureCount == 0)
{
if (challenge.ProtectionSpace.AuthenticationMethod.Equals("NSURLAuthenticationMethodServerTrust"))
{
// GetParent is correct, because I'm too lazy to copy the certs into to the correct folders...
var path = Directory.GetParent(GlobaleObjekte.SSLZertifikatePath);
var caPath = Path.Combine(path.FullName, "ca.cert.der");
var caByteArray = File.ReadAllBytes(caPath);
var caCert = new X509Certificate2(caByteArray);
var interPath = Path.Combine(path.FullName, "intermediate.cert.der");
var interByteArray = File.ReadAllBytes(interPath);
var interCert = new X509Certificate2(interByteArray);
var secTrust = challenge.ProtectionSpace.ServerSecTrust;
var certCollection = new X509CertificateCollection();
certCollection.Add(caCert);
certCollection.Add(interCert);
secTrust.SetAnchorCertificates(certCollection);
var credential = new NSUrlCredential(secTrust);
completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
return;
}
if (challenge.ProtectionSpace.AuthenticationMethod.Equals("NSURLAuthenticationMethodClientCertificate"))
{
var path = Directory.GetParent(GlobaleObjekte.SSLZertifikatePath);
var certPath = Path.Combine(path.FullName, "client.pfx");
var certByteArray = File.ReadAllBytes(certPath);
var cert = new X509Certificate2(certByteArray, Settings.WSClientCertPasswort);
var ident = SecIdentity.Import(certByteArray, Settings.WSClientCertPasswort);
var credential = new NSUrlCredential(ident, new SecCertificate[] { new SecCertificate(cert) }, NSUrlCredentialPersistence.ForSession);
completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
return;
}
if (challenge.ProtectionSpace.AuthenticationMethod.Equals("NSURLAuthenticationMethodHTTPBasic"))
{
var credential = new NSUrlCredential(Settings.WebserviceBenutzer, Settings.WebservicePasswort, NSUrlCredentialPersistence.ForSession);
completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
return;
}
completed_callback(false, "Unbekannte Authentifizierungsanfrage: " + challenge?.ProtectionSpace?.AuthenticationMethod);
}
else
{
completed_callback(false, "Authentifizierung fehlgeschlagen: " + challenge?.ProtectionSpace?.AuthenticationMethod);
}
}
}
私有类SessionDelegate:NSUrlSessionDataDelegate,InsuralSessionDelegate
{
私人行动完成(u回调);;
私有字符串antwortCache;
专用int状态代码;
公共会话Legate(操作已完成)
{
已完成的回调=已完成;
antwortCache=“”;
}
public override void DidReceiveChallenge(NSUrlSession会话、NSUrlSessionTask任务、NSURAuthenticationChallenge挑战、Action completionHandler)
{
if(challenge.PreviousFailureCount==0)
{
if(challenge.ProtectionSpace.AuthenticationMethod.Equals(“nsurAuthenticationMethodServerTrust”))
{
//GetParent是正确的,因为我太懒了,无法将证书复制到正确的文件夹中。。。
var path=Directory.GetParent(GlobaleObjekte.SSLZertifikatePath);
var caPath=Path.Combine(Path.FullName,“ca.cert.der”);
var caByteArray=File.ReadAllBytes(caPath);
var caCert=新的X509Certificate2(caByteArray);
var interPath=Path.Combine(Path.FullName,“intermediate.cert.der”);
var interByteArray=File.ReadAllBytes(interPath);
var interCert=新的X509Certificate2(跨字节数组);
var secTrust=challenge.ProtectionSpace.ServerSecTrust;
var certCollection=new X509CertificateCollection();
certCollection.Add(caCert);
certCollection.Add(插入);
部门信任。SetAnchorCertificates(certCollection);
var凭证=新NSUrlCredential(扇区信任);
completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential,credential);
返回;
}
if(challenge.ProtectionSpace.AuthenticationMethod.Equals(“NSURLAuthenticationMethodClientCertificate”))
{
var path=Directory.GetParent(GlobaleObjekte.SSLZertifikatePath);
var certPath=Path.Combine(Path.FullName,“client.pfx”);
var certByteArray=File.ReadAllBytes(certPath);
var cert=new X509Certificate2(certByteArray,Settings.WSClientCertPasswort);
var ident=SecIdentity.Import(certByteArray,Settings.WSClientCertPasswort);
var-credential=new-NSUrlCredential(ident,new-SecCertificate[]{new-SecCertificate(cert)},NSUrlCredentialPersistence.ForSession);
completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential,credential);
返回;
}
if(challenge.ProtectionSpace.AuthenticationMethod.Equals(“nsurAuthenticationMethodHttpBasic”))
{
var credential=新的NSUrlCredential(Settings.WebserviceBenutzer、Settings.WebservicePasswort、NSUrlCredentialPersistence.ForSession);
completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential,credential);
返回;
}
已完成的_回调(false,“unbekannette authenticfizierungsanfrage:+challenge?.ProtectionSpace?.AuthenticationMethod”);
}
其他的
{
已完成的_回调(false,“Authentifizierung fehlgeschlagen:“+challenge?.ProtectionSpace?.AuthenticationMethod”);
}
}
}
我终于找到了一个解决方案。我必须以不同的方式创建凭证对象。我没有将证书添加到SecTrust并使用SecTrust作为参数创建凭证,而是必须从客户端证书创建一个标识,然后使用标识和其他证书作为参数创建凭证卢比:
if (challenge.ProtectionSpace.AuthenticationMethod.Equals("NSURLAuthenticationMethodServerTrust"))
{
var path = Directory.GetParent(GlobaleObjekte.SSLZertifikatePath);
var caPath = Path.Combine(path.FullName, "ca.cert.der");
var caByteArray = File.ReadAllBytes(caPath);
var caCert = new SecCertificate(caByteArray);
var interPath = Path.Combine(path.FullName, "intermediate.cert.der");
var interByteArray = File.ReadAllBytes(interPath);
var interCert = new SecCertificate(interByteArray);
var clientPath = Path.Combine(path.FullName, "client.pfx");
var clientByteArray = File.ReadAllBytes(clientPath);
var clientCert = new X509Certificate2(clientByteArray, Settings.WSClientCertPasswort);
//var secTrust = challenge.ProtectionSpace.ServerSecTrust;
//var certCollection = new X509CertificateCollection();
//certCollection.Add(caCert);
//certCollection.Add(interCert);
//certCollection.Add(cert);
//secTrust.SetAnchorCertificates(certCollection);
//var credential = new NSUrlCredential(secTrust);
var identity = SecIdentity.Import(clientCert);
var credential = new NSUrlCredential(identity, new SecCertificate[] { caCert, interCert }, NSUrlCredentialPersistence.ForSession);
completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
return;
}
我想也许您应该使用NSUrlSessionDelegate进行一些工作。请参阅。在您的链接中,用户没有使用客户端身份验证,而只是使用自签名证书。这已经适用于我发布的NSUrlSessionDelegate实现。我的问题是,这仅在服务器同时请求客户端证书时才起作用te进行身份验证。也许能帮上忙。