我想从EC_KEY
导出公钥和私钥,这是从OpenSSL创建的,我们知道EC_KEY
保持密钥对,但openssl与将密钥对存储到安全区域不兼容。所以我想从OpenSSL创建证书并从那里创建密钥对,然后将密钥从EC_KEY
导出到SecKeyRef,然后创建密钥对并存储在Secure Enclave中。
EC_KEY
导出私人公钥并将其转换为SecRefKey 我从OpenSSL完成了第一部分从eliptic曲线EC_KEY
创建的证书,并且还完成了最后一部分以创建Keypair。下面是创建Keypair的代码。
- (void)generateKeyPair:(NSUInteger)keySize {
OSStatus sanityCheck = noErr;
publicKey = NULL;
privateKey = NULL;
// LOGGING_FACILITY1( keySize == 512 || keySize == 1024 || keySize == 2048, @"%d is an invalid and unsupported key size.", keySize );
// First delete current keys.
// [self deleteAsymmetricKeys];
// Container dictionaries.
NSMutableDictionary * privateKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary * publicKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary * keyPairAttr = [[NSMutableDictionary alloc] init];
// Set top level dictionary for the keypair.
[keyPairAttr setObject:(__bridge id)kSecAttrKeyTypeEC forKey:(__bridge id)kSecAttrKeyType];
[keyPairAttr setObject:[NSNumber numberWithUnsignedInteger:keySize] forKey:(__bridge id)kSecAttrKeySizeInBits];
[keyPairAttr setObject:(__bridge id)kSecAttrTokenID forKey:(__bridge id)kSecAttrTokenIDSecureEnclave];
// [keyPairAttr setObject:(__bridge id)kSecAttrTokenID forKey:(__bridge id)kSecAttrTokenIDSecureEnclave];
// Set the private key dictionary.
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecAttrIsPermanent];
[privateKeyAttr setObject:privateTag forKey:(__bridge id)kSecAttrApplicationTag];
// See SecKey.h to set other flag values.
// Set the public key dictionary.
[publicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecAttrIsPermanent];
[publicKeyAttr setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];
// See SecKey.h to set other flag values.
// Set attributes to top level dictionary.
[keyPairAttr setObject:privateKeyAttr forKey:(__bridge id)kSecPrivateKeyAttrs];
[keyPairAttr setObject:publicKeyAttr forKey:(__bridge id)kSecPublicKeyAttrs];
// SecKeyGeneratePair returns the SecKeyRefs just for educational purposes.
sanityCheck = SecKeyGeneratePair((__bridge CFDictionaryRef)keyPairAttr, &publicKey, &privateKey);
// LOGGING_FACILITY( sanityCheck == noErr && publicKey != NULL && privateKey != NULL, @"Something really bad went wrong with generating the key pair." );
if(sanityCheck == noErr && publicKey != NULL && privateKey != NULL)
{
NSLog(@"Successful");
}
// [privateKeyAttr release];
// [publicKeyAttr release];
// [keyPairAttr release];
}
答案 0 :(得分:0)
您无法导入任何安全区域。您只能使用SecKeyGeneratePair
生成密钥对(正如您在代码中所做的那样)
以下是Apple的文档中对此的引用:https://developer.apple.com/reference/security/keychain_services/token_id_values
生成后,您可以:
SecKeyRawSign
)SecKeyRawVerify
)SecKeyCreateEncryptedData
,SecKeyCreateDecryptedData
)SecItemCopyMatching
),随心所欲地做任何事情如果你想与OpenSSL互操作,你只需要将它们转换成OpenSSL可以读取的东西(例如PEM,DER等)
这里是一个简单的公钥从原始字节转换(SecItemCopyMatching
在kSecValueData下的字典中提供的内容)到PEM
+ (NSString*) openSSLPubKey:(NSData*) rawPublicKeyBytes {
uint8_t curveOIDHeader[] = {0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00};
NSMutableData* data = [[NSMutableData alloc] initWithBytes:curveOIDHeader length:26];
[data appendData:rawPublicKeyBytes];
NSString* base64EncodedString = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength | NSDataBase64EncodingEndLineWithCarriageReturn];
return [NSString stringWithFormat:@"-----BEGIN PUBLIC KEY-----\n%@\n-----END PUBLIC KEY-----",base64EncodedString];
}
请注意,您只能在安全区域中存储256位椭圆曲线私钥,因此硬编码的OID标头