SecKeyCreatePair创建两个SecKeyRef后如何创建CSR?

发布于 2025-01-02 05:40:20 字数 177 浏览 1 评论 0原文

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

I use SecKeyCreatePair to create the RSA key pair. The result is two key, pubkey & privkey. Now I want to get the raw data of pubkey to make a Certificate Request.
I can make a CSR by OpenSSL's X509_REQ* apis, but I don't known how to transform the pubkey of SecKeyRef type to raw key.
Is there anyone do this before?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倚栏听风 2025-01-09 05:40:20

看一下这个代码。要点是,一旦创建了密钥对,就必须指示 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;
}

Have a look at this code. The main point is that, once you have created the key pair, you have to instruct openssl to use them. To do that you need to supply the RSA key with new methods to do encryption and decryption using the keychain keys.

I've modified a bit the set_private_key function because if you want to create a CSR with openssl, you need the correct values of the public key's module and exponent.
So here it is:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文