我一直在网上看到.cer文件是什么以及如何生成它的脱节帐户,以便应用程序可以通过https与服务器正确通信。
引用this来源,有人说:
1)您现在需要捆绑包中的.cer文件来获取链中的所有证书。因此,至少必须存在两个证书文件(您的证书和根CA)。在我们的例子中,我们也需要一个中间体。
2)这些证书必须按特定顺序排列。具体而言,证明与之通信的主机的证书必须位于固定证书/密钥列表中的第一位。看起来它们其余部分的顺序并不重要。这是因为AFSecurityPolicy使用数组中的第一个对象来验证主机名。
3)如果要与根域通信,则通配符证书的主机验证将失败。例如,考虑一个指向* .foo.com的证书。如果您正在与foo.com通信,则主机检查将失败,因为主机组件计数将不匹配。我理解这种早期优化的必要性,但它甚至在它达到专门处理通配符域的逻辑之前就失败了。
官方文档支持here。
我认为为了生成这个,必须按照特定的顺序将整个证书链的内容捕获到.cer文件中。我记得看到这张贴在某个地方,但似乎无法找到它。
问题是,为AFNetworking创建.cer文件的不可取的方法是什么?
更新:
经过更多的研究,在我看来,你只需要使用.crt文件并在其上执行此操作:
openssl x509 -in www.mydomain.com.crt -out www.mydomain.com.cer -outform der
但是,即使在执行此操作并将.cer附加到我的应用程序包后,我也会收到错误:
+ (NSArray *)pinnedPublicKeys {
static NSArray *_pinnedPublicKeys = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSArray *pinnedCertificates = [self pinnedCertificates];
NSMutableArray *publicKeys = [NSMutableArray arrayWithCapacity:[pinnedCertificates count]];
for (NSData *data in pinnedCertificates) {
SecCertificateRef allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)data);
NSParameterAssert(allowedCertificate);
错误出现在最后一行。我想在上一行尝试分配allowedCertificate
时,SecCertificateCreateWithData
有以下描述:
/*!
@function SecCertificateCreateWithData
@abstract Create a certificate given it's DER representation as a CFData.
@param allocator CFAllocator to allocate the certificate with.
@param certificate DER encoded X.509 certificate.
@result Return NULL if the passed-in data is not a valid DER-encoded
X.509 certificate, return a SecCertificateRef otherwise.
*/
显然它返回NULL,但我不知道为什么。我的具体证书格式正确。但是,我确实注意到还有其他证书'在pinnedCertificates
数组中,但我不知道它在哪里得到它们。我似乎也无法找到它们或将它们打印出来。据我所知,我只在应用程序包中有一个,但它似乎显示的不止于此。
最后一行断言产生的错误是:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: allowedCertificate'
答案 0 :(得分:0)
假设您正在使用AFNetworking 2.5,请执行以下步骤:
创建.cer文件openssl x509 -in www_yourdomain_com.crt -out www_yourdomain_com.cer -outform der
将.cer文件添加到app项目。重要提示:永远不要在项目中添加私钥!!!
设置AFNetworking安全政策
- (AFSecurityPolicy *)securityPolicy {
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
[securityPolicy setAllowInvalidCertificates:NO];
[securityPolicy setValidatesDomainName:YES];
return securityPolicy;
}
进行网络呼叫时在网络管理器上设置策略
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager setSecurityPolicy:[self securityPolicy]];
如果您使用policyWithPinningMode:pinningMode
方法创建安全策略,则无需手动加载.cer文件,AFNetworking会自动将其固定。