[英]Converting a PrivateKey (SecRefKey) into NSData or Base64
我有一個 p12 文件,從中提取 PrivateKey、PublicKey 作為 SecKeyRef 和作為 SecCertificateRef 的證書。
P12 文件有一個 ECDSA PrivateKey,我需要用它來簽署數據 (ECC)。
所以我使用了一個建議的庫: https : //github.com/ricmoo/GMEllipticCurveCrypto
但是我需要用 Base64 或 NSData 上的密鑰提供庫,我無法提供 SecKeyRef。 我設法使用此處提供的方法為 publicKey 提取 NSData,它有效。
但是我找不到任何方法將指向私有密鑰的 SecRefKey 轉換為 NSData。 關於如何做到這一點的任何想法,或者,使用帶有 SecKeyRefs 的 ECC 在 iOS 中簽名和驗證數據。
作為參考,此方法將 P12 轉換為 iOS SecRefs:
- (BOOL)storeDetailsForP12CertificateData:(NSData *)certData password:(NSString*)pass identifier:(NSString*)identifier{
SecKeyRef publicKey, privateKey;
SecCertificateRef certRef;
//Extract keys and Certificate
NSMutableDictionary * options = [[NSMutableDictionary alloc] init];
[options setObject:pass forKey:(id)kSecImportExportPassphrase];
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = SecPKCS12Import((CFDataRef) certData,
(CFDictionaryRef)options, &items);
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
SecIdentityRef identityApp =
(SecIdentityRef)CFDictionaryGetValue(identityDict,
kSecImportItemIdentity);
assert(securityError == noErr);
//get private key
SecIdentityCopyPrivateKey(identityApp, &privateKey);
//get certificate
SecIdentityCopyCertificate(identityApp, &certRef);
//evaluate certificate.
CFArrayRef certs = CFArrayCreate(kCFAllocatorDefault, (const void **) &certRef, 1, NULL);
SecPolicyRef policy = SecPolicyCreateBasicX509();
SecTrustRef trust;
SecTrustCreateWithCertificates(certs, policy, &trust);
(CFRelease(certs));
SecTrustResultType trustResult;
SecTrustEvaluate(trust, &trustResult);
//get publickey
publicKey = SecTrustCopyPublicKey(trust);
//clean memory
(CFRelease(trust));
(CFRelease(policy));
if (!publicKey || !privateKey || !certRef) {
return NO;
} else {
KeyData *details = [[KeyData alloc] init];
details.publicKey = publicKey;
details.privateKey = privateKey;
details.certificate = certRef;
details.fileData = certData;
return YES;
}
}
看起來你只需要使用SecKeyCopyExternalRepresentation
:
/*!
@function SecKeyCopyExternalRepresentation
@abstract Create an external representation for the given key suitable for the key's type.
@param key The key to be exported.
@param error On error, will be populated with an error object describing the failure.
See "Security Error Codes" (SecBase.h).
@result A CFData representing the key in a format suitable for that key type.
@discussion This function may fail if the key is not exportable (e.g., bound to a smart card or Secure Enclave).
The format in which the key will be exported depends on the type of key:
* kSecAttrKeyTypeRSA PKCS#1 format
* kSecAttrKeyTypeECSECPrimeRandom SEC1 format (www.secg.org)
*/
CFDataRef _Nullable SecKeyCopyExternalRepresentation(SecKeyRef key, CFErrorRef *error)
請注意, CFDataRef
是免費橋接到NSData
,因此您可以輕松地轉換它們。
要為 SEC 導出私鑰,您需要檢索 SecKey 並將其轉換為 base64(並將結果格式化為每行最多 64 個字符。這里是 Swift 5 代碼:
var keyResult: CFTypeRef?
var statusCode = SecItemCopyMatching(attributes as CFDictionary, &keyResult)
if statusCode == noErr && keyResult != nil {
if let privateKey = SecKeyCopyExternalRepresentation(keyResult as! SecKey, nil) as Data? {
print("Private Key: \((privateKey.base64EncodedString()))")
}
return (keyResult as! SecKey)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.