来自SecKeyRef的公钥字节

时间:2016-04-25 14:32:47

标签: c macos

我需要从公钥SecKeyRef获取原始公钥字节(使用openssl,这是' der'格式)以实现公钥密码。实际的固定功能已经写好,无法更改,并带有一个unsigned char * pubkey,size_t pubkeylen用来比较它的引脚。

这是我到目前为止所尝试的:

SecTrustRef trust;
OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
SecKeyRef keyRef = SecTrustCopyPublicKey(trust);

CFDataRef publicKeyBits;

OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL, &publicKeyBits) == errSecSuccess;
//OSStatus success = SecItemExport(keyRef, kSecFormatPEMSequence, 0, NULL, &publicKeyBits) == errSecSuccess;

size_t pubkeylen = CFDataGetLength(publicKeyBits);
printf("pubkeylen: %d\n", pubkeylen);
unsigned char *pubkey = CFDataGetBytePtr(publicKeyBits);

问题是这似乎根本不是DER格式,我希望pubkeylen对于这个特定的键是550,但它打印526,并且数据也不正确。我也尝试了kSecFormatPEMSequence,然后用相同的结果对它进行base64解码(它确实变成了与之前相同的526长度数组,所以至少它是一致的)。

编辑: 看起来当导出到kSecFormatPEMSequence时,PEM包含: -----开始RSA公钥----- 而不是预期的 -----开始公钥----- 这是一种不对DER进行base64-decode的不同格式,也许可以通过更多API调用将其解析回DER格式?

我错过了什么?谢谢你的帮助!

编辑: 我也尝试了以下内容:

CFDataRef d_tag = CFDataCreate(NULL, "com.bob", 7);

const void *cKeys[] = {kSecClass, kSecAttrKeyType,
     kSecAttrKeyClass, kSecValueData,
    kSecReturnData
};
const void *cValues[] = {kSecClassKey, kSecAttrKeyTypeRSA,
     kSecAttrKeyClassPublic, keyRef,
    kCFBooleanTrue
};

CFDictionaryRef saveDict = CFDictionaryCreate(NULL, cKeys, cValues,
  5L, NULL, NULL);

OSStatus secStatus = SecItemCopyMatching(saveDict, (CFTypeRef)&publicKeyBits);
if (secStatus == errSecDuplicateItem ) {
    printf("errSecDuplicateItem\n");
    SecItemDelete(saveDict);
    secStatus = SecItemAdd(saveDict, (CFTypeRef)&publicKeyBits );
}

if ( secStatus != noErr ) {
    printf("return NULL\n");
    return NULL;
}

size_t pubkeylen = CFDataGetLength(publicKeyBits);
printf("pubkeylen: %d\n", pubkeylen);
unsigned char *pubkey = CFDataGetBytePtr(publicKeyBits);

结果更糟糕,pubkeylen一直是96,但是pubkey中的数据总是不同!

我还尝试从objective-c转换https://github.com/datatheorem/TrustKit/blob/master/TrustKit/Pinning/public_key_utils.m#L65,我得到:

OSStatus resultAdd, resultDel = noErr;
CFDataRef d_tag = CFDataCreate(NULL, "com.bobe", 9);

const void *peerPublicKeyAddcKeys[] = {kSecClass, kSecAttrApplicationTag,
     kSecValueRef, kSecAttrAccessible, kSecReturnData
};
const void *peerPublicKeyAddcValues[] = {kSecClassKey, d_tag,
     keyRef, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
    kCFBooleanTrue
};

CFDictionaryRef peerPublicKeyAdd = CFDictionaryCreate(NULL, peerPublicKeyAddcKeys, peerPublicKeyAddcValues,
  5L, NULL, NULL);

const void *publicKeyGetcKeys[] = {kSecClass, kSecAttrApplicationTag,
     kSecReturnData
};
const void *publicKeyGetcValues[] = {kSecClassKey, d_tag,
    kCFBooleanTrue
};

CFDictionaryRef publicKeyGet = CFDictionaryCreate(NULL, publicKeyGetcKeys, publicKeyGetcValues,
  3L, NULL, NULL);

resultAdd = SecItemAdd(peerPublicKeyAdd, &publicKeyBits);
resultDel = SecItemDelete(publicKeyGet);

if ((resultAdd != errSecSuccess) || (resultDel != errSecSuccess))
{
    // Something went wrong with the Keychain we won't know if we did get the right key data
    printf("return NULL\n");
    return NULL;
}

这次publicKeyBits总是为NULL,我开始把头发撕成碎片了!

0 个答案:

没有答案