新しい 10.7 API を使用してプライベート ECDSA キーをエクスポートしたいのですSecurity.framework
が、操作がエラー コード -26260 で失敗し続けます。
errSecPassphraseRequired = -25260, /* Passphrase is required for import/export. */
また、生成したキーはキーチェーンに追加されないようにしたいと考えています。これらのキーは他のマシンで使用するためのものであり、自分でストレージを処理するからです。これは機能しないコードです。最初のエクスポートは成功しますが、一度インポートされた同じキー データは、パスフレーズなしでは再度エクスポートできません。この鍵にパスフレーズを設定していません。ラップされた OpenSSL と PEM 防御を含むエクスポート タイプの多くの組み合わせを試しましたが、違いはないようです。すでに OpenSSL を使用してこれを行う作業コードがありますが、Lion では廃止されているため、新しい API で何ができるかを確認したかったのです。
// Set up the parameters for 256-bit ECDSA
CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeECDSA);
CFDictionarySetValue(parameters, kSecAttrKeySizeInBits, CFSTR("256")); // kSecp256r1
CFDictionarySetValue(parameters, kSecAttrIsPermanent, kCFBooleanFalse);
// Issue #1:
// SecKeyGeneratePair() adds the keys to the keychain, which I don't want to do
// The docs say that kSecAttrIsPermanent should change this behavior
SecKeyRef publicKey, privateKey;
OSStatus result = SecKeyGeneratePair((CFDictionaryRef)parameters, &publicKey, &privateKey);
CFRelease(parameters), parameters = nullptr;
if(noErr == result) {
CFDataRef privateKeyData = nullptr;
result = SecItemExport(privateKey, kSecFormatUnknown, 0, nullptr, &privateKeyData);
if(noErr == result) {
CFShow(privateKeyData);
uint32_t format = kSecFormatUnknown;
uint32_t itemType = kSecItemTypePrivateKey;
CFArrayRef items = nullptr;
result = SecItemImport(privateKeyData, nullptr, &format, &itemType, 0, nullptr, nullptr, &items);
CFRelease(privateKeyData), privateKeyData = nullptr;
CFRelease(privateKey), privateKey = nullptr;
if(noErr == result) {
privateKey = (SecKeyRef)CFRetain(CFArrayGetValueAtIndex(items, 0));
CFRelease(items), items = nullptr;
// Issue #2:
// SecItemExport() fails with -25260
result = SecItemExport(privateKey, kSecFormatUnknown, 0, nullptr, &privateKeyData);
if(noErr == result) {
CFShow(privateKeyData);
CFRelease(privateKeyData), privateKeyData = nullptr;
}
else
printf("SecItemExport error: %d\n", result);
}
else
puts("SecItemImport failed");
}
else
printf("SecItemExport error: %d\n", result);
}
else
printf("SecKeyGeneratePair error: %d\n", result);
サンプル実行の出力は次のとおりです。
<CFData 0x10061b390 [0x7fff79ed3fa0]>{length = 121, capacity = 256, bytes = 0x307702010104209432679e712a4ac156 ... 219ffed31a54aff1}
SecItemExport error: -25260