导出私钥时,SecItemExport失败

时间:2012-06-26 11:26:42

标签: macos security osx-lion core-foundation

我想使用新的10.7 Security.framework API导出私有ECDSA密钥,但操作仍然失败,错误代码为-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

0 个答案:

没有答案