Openssl 如何在SecKeyCreatePair生成两个SecKeyRef后生成CSR?

Openssl 如何在SecKeyCreatePair生成两个SecKeyRef后生成CSR?,openssl,keychain,Openssl,Keychain,我使用SecKeyCreatePair创建RSA密钥对。结果是两个键,pubkey和privkey。现在,我想获取pubkey的原始数据以进行证书请求。 我可以通过OpenSSL的X509_REQ*API创建CSR,但我不知道如何将SecKeyRef类型的pubkey转换为原始密钥。 以前有人这样做过吗 看看这个。要点是,一旦创建了密钥对,就必须指示openssl使用它们。为此,您需要为RSA密钥提供使用密钥链密钥进行加密和解密的新方法 我对set_private_key函数做了一些修改,因为如

我使用SecKeyCreatePair创建RSA密钥对。结果是两个键,pubkey和privkey。现在,我想获取pubkey的原始数据以进行证书请求。 我可以通过OpenSSL的X509_REQ*API创建CSR,但我不知道如何将SecKeyRef类型的pubkey转换为原始密钥。 以前有人这样做过吗

看看这个。要点是,一旦创建了密钥对,就必须指示openssl使用它们。为此,您需要为RSA密钥提供使用密钥链密钥进行加密和解密的新方法

我对set_private_key函数做了一些修改,因为如果要使用openssl创建CSR,需要公钥的模块和指数的正确值。 这就是:

static int set_private_key(EVP_PKEY *pkey, SecKeyRef privKey, SecKeyRef pubKey)
{
struct kc_rsa *kc = NULL;
RSA *rsa = NULL;
int ret = 0;
CFDataRef key_data = NULL;
const unsigned char * p = NULL;
OSStatus status = 0;
long len  = 0;

kc = (kc_rsa*) calloc(1, sizeof(struct kc_rsa));
if (!kc){
    GOTO_ERR("out of memory");
}
kc->item = privKey;

// we have to export the public key (CSSM does not give us a way to get 'e' and 'n')
status = SecKeychainItemExport(pubKey, kSecFormatBSAFE, 0, NULL, &key_data);
if (status){
    GOTO_ERR("SecKeychainItemExport failed");
}
p = (unsigned char *) CFDataGetBytePtr(key_data);
len =  CFDataGetLength(key_data);

d2i_PublicKey(EVP_PKEY_RSA, &pkey, &p, len);
rsa = EVP_PKEY_get1_RSA(pkey);
if (!rsa){
    GOTO_ERR("d2i_PublicKey fails");
}

{
    SecKeychainAttributeList *attrs = NULL;
    uint32_t size;

    if (getAttribute(privKey, kSecKeyKeySizeInBits, &attrs)){
        GOTO_ERR("getAttribute failed");
    }
    size = *(uint32_t *)attrs->attr[0].data;
    SecKeychainItemFreeAttributesAndData(attrs, NULL);

    kc->keysize = (size + 7) / 8;
}

RSA_set_method(rsa, &kc_rsa_pkcs1_method);
ret = RSA_set_app_data(rsa, kc);
if (ret != 1)
    GOTO_ERR("RSA_set_app_data");

EVP_PKEY_assign_RSA(pkey,rsa);
CFRetain(privKey);
err:
if(key_data)
    CFRelease(key_data);
return ret;
}

换个角度试试。创建CSR,获取证书,然后将证书和私钥导入密钥链。@Max,谢谢你的建议。我已经钩住了openssl的API并使其正常工作。我认为您的方式也可以很好地工作。您使用了哪种API将SecKeyRef(public和private)转换为EVP_PKEY?