iOS - 以编程方式安装SSL证书
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS - 以编程方式安装SSL证书相关的知识,希望对你有一定的参考价值。
我正在编写一个phonegap插件,可以在app keychain中安装CA根证书和用户证书。
以下是用于安装证书的代码:
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:certpath];
CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data;
CFStringRef password = (CFStringRef)certPassword;
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);
if (securityError == 0) {
NSLog(@" *** Certificate install Success ***");
} else {
NSLog(@" *** Certificate install Failure ***");
}
上面的代码工作正常(securityError等于0)。但是,我正在获取这些错误:
unknown apsd[59] <Warning>: <APSCourier: 0xee1ba80>: Stream error occurred for <APSTCPStream: 0x126940>: TLS Error Code=-9844 "peer dropped connection before responding"
unknown securityd[638] <Error>: CFReadStream domain: 12 error: 8
这表示设备不接受已安装的证书,因此我想知道证书未针对设备上安装的CA根证书进行验证。
我是否必须为应用程序安装CA根证书?
有任何想法吗 ?
P.S:我是Objective-C和XCode环境的新手。
编辑:
以下代码用于在钥匙串中存储CA根证书:
NSString *rootCertPath = [[NSBundle mainBundle] pathForResource:@"rootca" ofType:@"cer"];
NSData *rootCertData = [NSData dataWithContentsOfFile:rootCertPath];
OSStatus err = noErr;
SecCertificateRef rootCert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef) rootCertData);
CFTypeRef result;
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassCertificate, kSecClass,
rootCert, kSecValueRef,
nil];
err = SecItemAdd((CFDictionaryRef)dict, &result);
if( err == noErr) {
NSLog(@"Install root certificate success");
} else if( err == errSecDuplicateItem ) {
NSLog(@"duplicate root certificate entry");
} else {
NSLog(@"install root certificate failure");
}
编辑:
似乎证书没有发送到服务器。我认为每次发出https请求时我都必须手动发送证书...我正在寻找一种方法来捕获phonegap中的每个https呼叫。
答案
将证书导入钥匙串是不够的。新的根证书也受到用户或系统的信任。
假设您在变量SecCertificateRef
中仍然有certificate
,请使用以下代码来提高信任级别:
NSDictionary *newTrustSettings = @{(id)kSecTrustSettingsResult: [NSNumber numberWithInt:kSecTrustSettingsResultTrustRoot]};
status = SecTrustSettingsSetTrustSettings(certificate, kSecTrustSettingsDomainUser, (__bridge CFTypeRef)(newTrustSettings));
if (status != errSecSuccess) {
NSLog(@"Could not change the trust setting for a certificate. Error: %d", status);
exit(0);
}
更改信任级别将在弹出窗口中询问用户是否接受更改。
另一答案
Swift 4.0
let rootCertPath = Bundle.main.path(forResource: "XXXXX", ofType: "der")
let rootCertData = NSData(contentsOfFile: rootCertPath!)
var err: OSStatus = noErr
let rootCert = SecCertificateCreateWithData(kCFAllocatorDefault, rootCertData!)
//var result: CFTypeRef1
let dict = NSDictionary.init(objects: [kSecClassCertificate, rootCert!], forKeys: [kSecClass as! NSCopying, kSecValueRef as! NSCopying])
err = SecItemAdd(dict, nil)
if(err == noErr) {
NSLog("Install root certificate success");
} else if( err == errSecDuplicateItem ) {
NSLog("duplicate root certificate entry");
} else {
NSLog("install root certificate failure");
}
另一答案
我正在寻找,为系统钥匙串证书设置“永远信任”,
// Trust always, as root certificated.
NSDictionary *newTrustSettings = @{(id)kSecTrustSettingsResult: [NSNumber numberWithInt:kSecTrustSettingsResultTrustRoot]};
status = SecTrustSettingsSetTrustSettings(myCertificate, kSecTrustSettingsDomainAdmin, (__bridge CFTypeRef)(newTrustSettings));
以上是关于iOS - 以编程方式安装SSL证书的主要内容,如果未能解决你的问题,请参考以下文章
在 InstallShield 安装期间导入 SSL 证书后,无法以编程方式将其与 IIS 中的绑定相关联