我正在构建一个需要.bks密钥库进行身份验证的iPhone应用程序。我没有找到任何关于iOS应用程序的信息。
我想知道苹果是否允许在他们的应用程序中使用密钥库以及如何开始使用iOS。证书使用BouncyCastle创建。我找不到有关Android的信息,但对于iOS,我没有运气。任何帮助将不胜感激。
答案 0 :(得分:2)
您可以像这样
从密钥库中导出所需的证书keytool -exportcert -keystore <keystore> -file some.cer
您可能需要告诉keytool商店类型和商店提供商look here。
您可以使用以下代码将.cer文件读入iOS钥匙串:
- (void) importCertToKeyChain: (NSData *) data
{
// Delete the old certificate, otherwise SecItemAdd complains.
OSStatus oss = SecItemDelete((__bridge CFDictionaryRef)([self clientCertificateQuery]));
// Import the certificate
SecCertificateRef certRef = NULL;
certRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(data));
NSDictionary *att = [NSDictionary dictionaryWithObjectsAndKeys: (__bridge id)(kSecClassCertificate), kSecClass, (__bridge id) certRef, kSecValueRef, nil];
oss = SecItemAdd((__bridge CFDictionaryRef)(att), NULL);
}
当您需要证书时,可以从钥匙串中获取证书:
- (SecCertificateRef) getCertFromKeyChain
{
CFTypeRef ref = NULL;
SecItemCopyMatching((__bridge CFDictionaryRef)([self clientCertificateQuery]), &ref);
return (SecCertificateRef) ref;
}
clientCertificateQuery看起来像这样。
static NSString *clientCertSubject = @"TestSubjectClient";
-(NSMutableDictionary *) clientCertificateQuery
{
NSMutableDictionary *query = [[NSMutableDictionary alloc] init];
[query setObject:(__bridge id) kSecClassCertificate forKey:(__bridge id)kSecClass];
[query setObject:clientCertSubject forKey:(__bridge id<NSCopying>)(kSecMatchSubjectContains)];
[query setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
id)kSecAttrKeyType];
return query;
}
还有一个读取PCKS12商店的功能(您仍然需要将BKS商店转换为该格式)。它被称为SecPKCS12Import
,使用它你不需要将证书导入你的iOS钥匙串。我没有运气,无论如何都需要钥匙串中的证书,但这里是something about this。
<强>更新强>
当在应用程序中包含包含秘密信息(如私钥)的证书时,不推荐使用上述方法在评论中指出的camdaochemgio。因为.cer文件不受保护,可以很容易地从.ipa中提取。
PKCS#P12支持密码保护,因此最好使用它。
你可以像这样将你的密钥库转换为PKCS#P12(采用from here):
keytool -importkeystore -srckeystore KEYSTORE.jks -destkeystore KEYSTORE.p12 -srcstoretype BKS -deststoretype PKCS12 -srcstorepass mysecret -deststorepass mysecret -srcalias myalias -destalias myalias -srckeypass mykeypass -destkeypass mykeypass -noprompt
然后你可以像这样加载.p12文件(信用转here)
// Load Certificate
NSString *path = [[NSBundle mainBundle] pathForResource:@"cert" ofType:@"p12"];
NSData *p12data = [NSData dataWithContentsOfFile:path];
CFDataRef inP12data = (__bridge CFDataRef)p12data;
// Only password based PKCS#12 blobs are supported
CFStringRef password = CFSTR("Password");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
// The import
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = SecPKCS12Import(inP12data, options, &items);
if (securityError == 0)
{
// Exploring the content
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
*identity = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
*trust = (SecTrustRef)tempTrust;
}
if (options) {
CFRelease(options);
}
关于此主题的最后但并非最不重要的一些链接: