【问题标题】:How can I get CSR from signature key pair如何从签名密钥对中获取 CSR
【发布时间】:2020-11-19 03:12:20
【问题描述】:

基于this tutorial,我已经成功创建了签名密钥对和Key Container。 创建后的密钥容器会存放在%AppData%\Roaming\Microsoft\Crypto\RSA文件夹中。

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

提前致谢。

【问题讨论】:

标签: c++ cryptography window x509certificate2 cng


【解决方案1】:
  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 */
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-20
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    相关资源
    最近更新 更多