简体   繁体   中英

Unable to use self signed certificate with AFNetworking 2

I put the .cer certificate used by the Apache Server in the Xcode project. When the app tries to talk to the server I get this error in Xcode:

Assertion failure in id AFPublicKeyForCertificate(NSData *__strong)(),
/Users/../ProjectName/AFNetworking/AFSecurityPolicy.m:52
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', 
reason: 'Invalid parameter not satisfying: allowedCertificate'

Here is the code for calling the server :

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[self setSecurityPolicy:[AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey]];
[manager POST:@"https://www.example.com/" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
//success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//failure
}];

I changed the pinning mode to AFSSLPinningModeCertificate with no luck.

and when I remove this line:

[self setSecurityPolicy:[AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey]];

the server responds with the error message:

"The operation couldn't be completed. (NSURLErrorDomain error -1012.)"

The certificate was created using OpenSSL, and I even tried a free certificate from StartSSL.com

As for the Apache Server side, here is the virtual host configuration:

# My custom host
<VirtualHost *:443>
    ServerName www.example.com
    DocumentRoot "/path/to/folder"
    SSLEngine on
    SSLCipherSuite HIGH:!aNULL:!MD5
    SSLCertificateFile /path/to/www.example.com.cer
    SSLCertificateKeyFile /path/to/www.example.com.key
    <Directory "/the/directory/">
        Options Indexes FollowSymLinks Includes ExecCGI
        AllowOverride All
        Require all granted
    </Directory>
    ErrorLog "logs/mysite.local-error_log"
</VirtualHost>

and the server does listen to the 443 port

It looks like your certificate file is not in the right format. Your code fails at these lines ( AFURLConnectionOperation/pinnedPublicKeys ):

SecCertificateRef allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)data);
NSParameterAssert(allowedCertificate);

I had the same error (on AFNetworking 1.1 , but the version should not matter), when my certificate was looking like this:

-----BEGIN CERTIFICATE-----
..
-----END CERTIFICATE----- 

I managed to resolve this by converting the certificate to x509 format, using the command from this answer :

openssl x509 -in adn.crt -outform der -out "adn.der"

Afterwards I renamed adn.der back to adn.cer ('.cer' seems to be the expected extension for AFNetworking ), and everything works well now.

The problem isn't on the side of AFNetworkings, but on iOS': You need to install the self-signed certificate on the device, because the iOS security settings forbid connections to untrusted sources.

You can add a self-signed certificate as a trusted source by opening the certificate on you iOS device (mail it to yourself and open it) and following the install instructions.

If required, you can disable the invalid certificate check by changing your security policy.

[self setAllowInvalidCertificates:YES];

Please read more in the documentation: http://cocoadocs.org/docsets/AFNetworking/2.0.3/Classes/AFSecurityPolicy.html#//api/name/allowInvalidCertificates

You can also pin the certificate: http://cocoadocs.org/docsets/AFNetworking/2.0.3/Classes/AFSecurityPolicy.html#//api/name/pinnedCertificates

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM