如何从签名密钥对中获取CSR



基于本教程,我已经成功创建了签名密钥对和密钥容器。创建后的密钥容器将存储在%AppData%\Roaming\Microsoft\Crypto\RSA文件夹中。

接下来,我想使用签名密钥对来获得CSR(证书签名请求(。那么我该怎么做呢?

提前谢谢。

  1. 如果使用CNG,则使用NCryptOpenKey获取NCRYPT_KEY_HANDLE密钥句柄(如果使用CAPI,则使用CryptAcquireContext获取HCRYPTPROV句柄(
  2. 使用CryptExportPublicKeyInfo导出公钥
  3. 使用CertStrToName对主题名称进行编码,例如:
DWORD EncodeCertificateName(const std::wstring& name_to_encode, const DWORD delim_flag, 
std::vector<BYTE>& encoded_name)
{
DWORD encoded_name_len = 0;
/* get length */
if (!CertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
name_to_encode.data(),
CERT_X500_NAME_STR | delim_flag,
NULL,
NULL,
&encoded_name_len,
NULL))
{
return GetLastError();
}

encoded_name.resize(encoded_name_len);
/* encode */
if (!CertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
name_to_encode.data(),
CERT_X500_NAME_STR | delim_flag,
NULL,
encoded_name.data(),
&encoded_name_len,
NULL))
{
return GetLastError();
}

return ERROR_SUCCESS;
}

std::wstring subject = L"CN=Test_request, E=test@test.com";
std::vector<BYTE> encoded_name;
EncodeCertificateName(subject, CERT_NAME_STR_COMMA_FLAG, &encoded_name);
  1. 填充CERT_REQUEST_INFO结构:

CERT_REQUEST_INFO cert_req_info;

/* set attributes if any */
cert_req_info.cAttribute = 0;
cert_req_info.rgAttribute = nullptr;

cert_req_info.dwVersion = CERT_REQUEST_V1;

/* set encoded subject name */
cert_req_info.Subject.cbData = static_cast<DWORD>(name_enc.size());
cert_req_info.Subject.pbData = name_enc.data();

/* set exported public key info */
cert_req_info.SubjectPublicKeyInfo = pub_key_info;
  1. 填充CRYPT_ALGORITHM_IDENTIFIER结构:

CRYPT_ALGORITHM_IDENTIFIER sig_alg;

/* set signature algorithm, for example */ 
sig_alg.pszObjId = szOID_RSA_SHA256RSA;
  1. 使用CryptSignAndEncodeCertificate和参数lpszStructType=X509_CERT_request_TO_BE_SIGNED创建证书请求:
std::vector<BYTE> enc_req_val;
DWORD enc_req_len = 0;
/* get length */
if (!CryptSignAndEncodeCertificate(hProv,
AT_SIGNATURE, 
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
X509_CERT_REQUEST_TO_BE_SIGNED,
&cert_req_info,
&sig_alg,
nullptr,
nullptr,
&enc_req_len))
{
/* handle error */
}
enc_req_val.resize(enc_req_len);
/* create certificate request */
if (!CryptSignAndEncodeCertificate(hProv,
AT_SIGNATURE, 
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
X509_CERT_REQUEST_TO_BE_SIGNED,
&cert_req_info,
&sig_alg,
nullptr,
enc_req_val.data(),
&enc_req_len))
{
/* handle error */
}

最新更新