iOS高级网络技术#保护网络传输#验证服务器通信

为了满足安全相关的需求,Apple向开发者提供了Security框架和CommonCrypto接口,可以在应用中使用。

Security框架是一套C API的集合,用于管理证书、信任策略以及对设备安全数据存储的访问。

CommonCrypto是一套接口的集合,用于数据的加解密、生成常见的密码散列(比如MD5和SHA1),计算消息认证码,生成密码或是基于密码的密钥等。

我们将会介绍如何使用Security框架与NSURLConnection来验证客户端与服务器的身份,还会介绍常见的认证模式,并提供一个关于加密传输数据的示例。和解密服务器响应,并使用设备的钥匙串安全的存储认证信息。

验证服务器通信

移动应用没法确保应用到Internet的连接是安全的,不会被其他人窥探。确保用户只与期望的服务器进行通信是开发者的职责。

最佳实践是使用NSURLProtectionSpace验证应用的用户与服务器进行通信。

下面展示如何创建保护空间:

NSURLProtectionSpace *defaultSpace = [[NSURLProtectionSpace alloc]
                                    initWithHost:@"yourbankingdomain.com"
                                    port:443
                                    protocol:NSURLProtectionSpaceHTTPS
                                    realm:@"mobile"
                                    authenticationMethod:NSURLAuthenticationMethodDefault];

既然已经使用服务器的属性创建了保护空间,你需要确保将其用于验证连接。实现willSendRequestForAuthenticationChallenge:可以检查挑战,确定是否想要响应服务器的认证挑战,同事发出恰当的挑战响应。

认证挑战响应是NSURLCredential的实例,可用于创建信任、用户名/密码组合和客户端证书。

-(void)connection:(NSURLConnection *)connection
willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSURLProtectionSpace *defaultSpace = [[NSURLProtectionSpace alloc]
                                          initWithHost:@"yourbankingdomain.com"
                                          port:443
                                          protocol:NSURLProtectionSpaceHTTPS
                                          realm:@"mobilebanking"
                                          authenticationMethod:NSURLAuthenticationMethodDefault];
    NSURLProtectionSpace *trustSpace = [[NSURLProtectionSpace alloc]
                                        initWithHost:@"yourbankingdomain.com"
                                        port:443
                                        protocol:NSURLProtectionSpaceHTTPS
                                        realm:@"mobilebanking"
                                        authenticationMethod:NSURLAuthenticationMethodClientCertificate];
    NSArray *validSpaces = @[defaultSpace, trustSpace];
    if (![validSpaces containsObject:challenge.protectionSpace])
    {
        NSString *msg = @"We are unable to establish a secure connection. Please check your network conection and try again.";
        dispatch_async(dispatch_get_main_queue(), ^
        {
            
        });
        [challenge.sender cancelAuthenticationChallenge:challenge];
    }
}

这种特定的验证会确保应用只与指定的服务器进行通信。如果发现处于恶意网络之上,传输被重新路由到第三方服务器,那么保护控件验证就会因不匹配的主机而失败,后续的通信也会终止。

扫描二维码关注公众号,回复: 12884221 查看本文章

实现后端灵活性的另一种方式是只验证认证挑战中的某些属性,比如主机、端口与协议是否与预先定义好的相匹配。

if (![challenge.protectionSpace.host isEqualToString:@"yourbankingdomain.com"] ||
    challenge.protectionSpace.port != 443 ||
    ![challenge.protectionSpace.protocol isEqualToString:NSURLProtectionSpaceHTTPS])
{
    //提示
    [challenge.sender cancelAuthenticationChallenge:challenge];
}

服务器验证是非常重要的,不过尚不足以阻止所有的攻击。要想确保用户数据的安全,还需要仔细评估和考虑其他一些安全度量,比如消息完整性与数据加密等。

猜你喜欢

转载自blog.csdn.net/run_in_road/article/details/113775108