我一直在网上看到.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'
最佳答案
假设您正在使用AFNetworking 2.5,请执行以下步骤:
在服务器上安装有效证书
创建.cer文件openssl x509 -in www_yourdomain_com.crt -out www_yourdomain_com.cer -outform der
将.cer文件添加到应用程序项目。重要提示:切勿在项目中添加私钥!!!
设置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会自动将其固定。