使用AFNetworking进行SSL Pinning

15

我的应用程序使用https和自签名的SSL证书来保护客户端和服务器之间的连接。

我试图让AFNetworking库对应用程序中捆绑的证书副本进行SSL Pinning。

AFURLConnectionOperation头文件中,我定义了:

#define _AFNETWORKING_ALLOW_INVALID_SSL_CERTIFICATES_ =1
#define _AFNETWORKING_PIN_SSL_CERTIFICATES_ =1

在调用我的AFJSONRequestOperationstart之前,我将SSLPinningMode属性设置为AFSSLPinningModeCertificate。但是,在尝试执行JSON请求时,我不停地收到以下错误:
Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. 
(NSURLErrorDomain error -1012.)" UserInfo=0x758f120 
{NSErrorFailingURLKey=https://mydomain.com,
NSErrorFailingURLStringKey=https://mydomain.com}

AFURLConnectionOperation头文件中,我发现SSL Pinning使用.cer证书,但是在我的自托管的OS X Web服务器上,我有一个.crt证书。
这是问题吗?有没有办法让AFNetworking与.crt一起工作?
在Windows框上,我将我的.crt转换为.cer,并尝试将其捆绑到我的应用程序中,但我仍然收到相同的错误。我应该尝试在服务器端切换.crt文件为新创建的.cer吗?

你找到答案了吗?能分享一下吗? - jAckOdE
我放弃使用AFNetworking,写了一个类来利用标准的NSURLConnection(并作为连接本身的代理)来发出请求,并在NSURLConnectionDelegate协议的- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge方法中手动处理比较的内容。如果您想查看代码,请随时提问。 - BigLex
我自己没有尝试过。但在AFNetworking示例项目中,SSL固定模式设置为AFSSLPinningModePublicKey,而不是AFSSLPinningModeCertificate。你试过吗? - jAckOdE
https://dev59.com/2X7aa4cB1Zd3GeqPlxdB#22696193 - k06a
3个回答

20

我解决了它。

我处于这样一种情况:我为了从我的iOS应用程序中访问自己的服务器API而创建了一个自签名证书。我使用OpenSSL创建了我的证书。当我完成创建后,有几个文件,其中一个是“server.crt”。最初,我尝试将其重命名为“server.cer”,并对我的AFURLConnectionOperation对象使用“AFSSLPinningModeCertificate”。但那行不通,我注意到示例使用了“AFSSLPinningModePublicKey”,所以我尝试了那个,但仍然没有成功。

于是我比较了我的文件(已被重命名为“.crt”文件)和他的文件。
我注意到“server.crt”是Base64编码的,像这样:

-----BEGIN CERTIFICATE-----
394230AFDFD... 
-----END CERTIFICATE-----

我从Mattt在AFNetworking中的示例中注意到他使用的"adn.cer"文件不是Base64编码。它只是原始字节。

所以,我也这样做了:
$ base64 -D -i ./server.crt -o ./server.cer

我将我的AFURLConnectionOperation设置为AFSSLPinningModePublicKey。
然后我将其放回项目中,清理并重新构建了我的iOS项目,所有东西都正常工作。

希望这可以帮到你!

顺便说一下,你可能会注意到Xcode会显示你的".crt"或".cer"密钥的信息,无论是base64还是原始的,所以不要让这让你困惑。无论哪种情况,你都应该能够看到证书数据,只是AF只接受原始(非base64)的数据。

更新:
任何遇到base64问题的人,在OS X上使用OpenSSL,以下方法适用于我:

$ openssl base64 -d -in ./server.crt -out ./server.cer

1
你的解决方法是正确的,但是如何在没有任何 .cer 文件的情况下使其工作呢?这才是问题所在! - Voda Ion
8
我用base64进行转换时遇到问题,最终我使用了命令'openssl x509 -in test.crt -outform der -out test.cer'来完成转换。 - CharlesA
2
@tanmaykhandelwal:那个链接现在已经失效了,但我注意到该内容已经重新发布在support.ssl.com上 - Matt Kantor
1
@firebear 我在我的帖子中添加了一个更新,希望能有所帮助! - jpswain
我在Mac上尝试了“openssl base64 -d -in ./server.crt -out ./server.cer”。是的,它起作用了!谢谢。 - firebear
显示剩余4条评论

3

如果你正在使用AFNetworking 2.x,并且使用了正确的.cer文件,但仍然在调用时收到错误代码-1012,则应禁用validatesCertificateChain

AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
securityPolicy.validatesCertificateChain = NO;

或者你可以在“pinnedCertificates”中传递整个证书链。

0

您的证书必须具有扩展名cer而不是crt,并且应该是.der格式。将输出文件添加到您的Xcode项目中。

您可以使用以下命令:

openssl x509 -in your.crt -out certificate_cer.cer -outform der


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