如何使用AFNetworking比较SSL证书

8
在我的iPhone应用程序中,我使用一个自签名的SSL证书和https连接从服务器下载敏感数据(用户名和密码)。这个应用程序仅供私人使用,不适用于生产环境。我正在使用AFNetworking来管理https连接,但是由于我的证书未经CA签名,为了使它工作,我不得不在AFURLConnectionOperation类的头部添加以下内容:
#define _AFNETWORKING_ALLOW_INVALID_SSL_CERTIFICATES_ 1

但是我的应用程序将允许任何证书。

是否有一种方法仅允许来自我的服务器的证书,可以将其捆绑在应用程序中并与https连接中服务器提供的证书进行比较? 如果可能的话,从安全角度来看是否存在任何重大优势?

我对安全非常陌生,有些困惑。

2个回答

21
您要查找的术语是SSL Pinning,应用程序会验证已知证书或公钥与远程服务器呈现的证书或公钥是否匹配。
AFNetworking支持使用证书或公钥进行pinning。您需要将证书或公钥添加到应用程序的Bundle中,并通过在AFHttpClient上设置defaultSSLPinningMode属性或在AFURLConnectionOperation上设置SSLPinningMode属性来启用该功能。
您可以使用AFSSLPinningModePublicKeyAFSSLPinningModeCertificate进行固定。 AFSSLPinningModeCertificate表示服务器的证书必须与包中的证书之一完全匹配。 AFSSLPinningModePublicKey更加自由,意味着服务器的证书必须与包中任何公钥或附加到包中证书的任何公钥匹配。
在AppDotNet示例中有一个设置固定模式的示例

1
SSL Pinning 提供了额外的保护,防止中间人攻击和受损的 CA。这里有一些见解(http://blog.lumberlabs.com/2012/04/why-app-developers-should-care-about.html)。 - David Snabel-Caunt
正是我想要的!最后一个问题,我需要以某种方式设置证书文件,使AFNetworking库可以将服务器提供的证书与之比较,还是库会自行找到它? - BigLex
1
AFNetworking会自动在bundle根目录中查找证书。 - David Snabel-Caunt
1
我的证书扩展名是.crt而不是.cer,当我尝试连接时,以下错误被记录在xcode中:Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x7157d40。头文件上说证书应该是.cer,这可能是问题所在吗? - BigLex
4
е°Ҷ.crtж–Ү件иҪ¬жҚўдёә.cerж–Ү件пјҡжү“ејҖз»Ҳз«Ҝ并иҝҗиЎҢд»ҘдёӢе‘Ҫд»ӨгҖӮopenssl x509 -in www.mydomain.com.crt -out www.mydomain.com.cer -outform der - Gabriel.Massana
显示剩余2条评论

8
稍微解释一下David的回答,关于AFSSLPinningModePublicKeyAFSSLPinningModeCertificate。理想情况下,您应该钉住公钥而不是证书。因为一些站点和服务,如Google,每30天左右会轮换其证书。但他们会重新认证相同的公钥。
证书经常轮换是为了保持移动客户端CRL的大小。但他们重新认证相同的公钥(而不是创建新的)以允许进行密钥连续性测试。
公钥固定是为什么像Certificate Patrol这样的工具会失效。证书预计会更改;公钥不会。
如果您熟悉它,公钥固定很像SSH的StrictHostKeyChecking
OWASP在Certificate and Public Key Pinning中也有相关介绍。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接