Determining Trust With NSURLConnection and NSURLProtectionSpace(使用 NSURLConnection 和 NSURLProtectionSpace 确定信任)
问题描述
我想就之前提出的问题提出一个后续问题一个>.我有创建 NSURLRequest/Connection 的代码,运行它并调用用于身份验证的回调方法.具体代码如下:
I would like to ask a followup question to a previously posed question. I've got the code to create an NSURLRequest/Connection, run it and have the callback methods for authentication get called. Here's the specific code:
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust] || [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodDefault];
}
-(void)connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge previousFailureCount] > 0) {
[[challenge sender] cancelAuthenticationChallenge:challenge];
NSLog(@"Bad Username Or Password");
badUsernameAndPassword = YES;
finished = YES;
return;
}
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
if (appDelegate._allowInvalidCert)
{
// Go ahead...trust me!
[challenge.sender useCredential:
[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]
forAuthenticationChallenge: challenge];
}
else
{
TrustGenerator *tg = [[TrustGenerator alloc] init];
if ([tg getTrust:challenge.protectionSpace])
{
// Go ahead...trust me!
[challenge.sender useCredential:
[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]
forAuthenticationChallenge: challenge];
}
else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
}
else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodDefault) {
NSURLCredential *newCredential = [NSURLCredential credentialWithUser:_username password:_password persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
}
}
我遇到的是带有[challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]"的didReceiveAuthenticationChallenge"总是被调用,即使我正在尝试服务器上的证书连接到是受信任的(使用 Verisign 证书进行测试).所以我看到的是我的应用程序总是提示最终用户信任,即使网站是受信任的.考虑到这是一个人在中间攻击中可能发生的事情,等等.我真正想要的是这样的代码:
What I'm running into is that "didReceiveAuthenticationChallenge" with "[challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]" is ALWAYS being called, even when the certificate on the server I'm attempting to connect to is trusted (doing testing with a Verisign cert). So what I'm seeing is my application is always prompting the end user to trust even when the website is trusted. Bad karma considering that's what's suppose to happen with a man in the middle attack, etc. What I'm really looking for is some code like this:
if (appDelegate._allowInvalidCert)
{
// Go ahead...trust me!
[challenge.sender useCredential:
[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]
forAuthenticationChallenge: challenge];
}
else if(The OS trusts the cert on the server)
{
[challenge.sender useCredential:
[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]
forAuthenticationChallenge: challenge];
}
else{...
推荐答案
所以我花了几天时间研究这个.看起来虽然 NSURLConnection API 无法确定证书是否可信,但安全框架中有一个方法可以处理它.所以这是我想出的代码:
So I spent a few days researching this. It looks like while the NSURLConnection API cannot determine if a certificate is trusted, there's a method in the Security Framework that handels that. So here's the code I came up with:
-(void)connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge previousFailureCount] > 0) {
[[challenge sender] cancelAuthenticationChallenge:challenge];
NSLog(@"Bad Username Or Password");
badUsernameAndPassword = YES;
finished = YES;
return;
}
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
SecTrustResultType result;
//This takes the serverTrust object and checkes it against your keychain
SecTrustEvaluate(challenge.protectionSpace.serverTrust, &result);
if (appDelegate._allowInvalidCert)
{
[challenge.sender useCredential:
[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]
forAuthenticationChallenge: challenge];
}
//When testing this against a trusted server I got kSecTrustResultUnspecified every time. But the other two match the description of a trusted server
else if(result == kSecTrustResultProceed || result == kSecTrustResultConfirm || result == kSecTrustResultUnspecified){
[challenge.sender useCredential:
[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]
forAuthenticationChallenge: challenge];
}
else
{
//Asks the user for trust
TrustGenerator *tg = [[TrustGenerator alloc] init];
if ([tg getTrust:challenge.protectionSpace])
{
//May need to add a method to add serverTrust to the keychain like Firefox's "Add Excpetion"
[challenge.sender useCredential:
[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]
forAuthenticationChallenge: challenge];
}
else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
}
else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodDefault) {
NSURLCredential *newCredential = [NSURLCredential credentialWithUser:_username password:_password persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
}
}
这篇关于使用 NSURLConnection 和 NSURLProtectionSpace 确定信任的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 NSURLConnection 和 NSURLProtectionSpace 确定信任
基础教程推荐
- iPhone - 获取给定地点/时区的当前日期和时间并将其与同一地点的另一个日期/时间进行比较的正确方法 2022-01-01
- libGDX 从精灵或纹理中获取像素颜色 2022-01-01
- navigator.geolocation.getCurrentPosition 在 Android 浏览器上 2022-01-01
- Cocos2d iPhone 非矩形精灵触摸检测 2022-01-01
- NSString intValue 不能用于检索电话号码 2022-01-01
- AdMob 广告未在模拟器中显示 2022-01-01
- 如何从 logcat 中删除旧数据? 2022-01-01
- Android:getLastKnownLocation(LocationManager.NETWORK_PROVIDER 2022-01-01
- iOS4 创建后台定时器 2022-01-01
- 通过重定向链接在 Google Play 中打开应用 2022-01-01
