首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用C++ CryptAPI:CNG Create CSR

使用C++ CryptAPI:CNG Create CSR
EN

Stack Overflow用户
提问于 2018-10-23 18:33:46
回答 1查看 262关注 0票数 1

正在尝试创建CSR并使用注册API。已成功创建私钥,并添加扩展。但无法使其生成CSR文本。我收到错误,因为无效的参数/参数或文件已存在(HRESULT)

我不想使用OPENSSL,依赖于WIN32 Crypto API来生成csr和存储证书。

我已经看过C#中的大部分样本了。我需要在C++中使用它。下面是我的示例代码WIN32 C++

代码语言:javascript
复制
    CComPtr<IX509CertificateRequestPkcs10> _csrquestpkcs10;
    CComPtr<IX509PrivateKey> _privateKey;
    CComPtr<ICspInformation> _cspInformation;
    CComPtr<ICspInformations> _cspInformations;
    CComPtr<IX500DistinguishedName> _distinguishName;
    CComPtr<IX509Enrollment> _enroll;
    CComPtr<IX509ExtensionKeyUsage> _extensionKeyUsage;
    CComPtr<IX509ExtensionEnhancedKeyUsage> _enhancedKeyUsageExtension;


    HRESULT hr = _cspInformation.CoCreateInstance(__uuidof(CCspInformation), NULL, CLSCTX_INPROC_SERVER);
    if (FAILED(hr)){
        return -1;
    }

    CComBSTR _proividerName(L"Microsoft Enhanced Cryptographic Provider v1.0");
    hr = _cspInformation->InitializeFromName(_proividerName);
    if (FAILED(hr)){
        return -1;
    }
    hr = _cspInformations.CoCreateInstance(__uuidof(CCspInformations), NULL, CLSCTX_INPROC_SERVER);
    if (FAILED(hr)){
        return -1;
    }
    hr = _cspInformations->Add(_cspInformation);
    if (FAILED(hr)){
        return -1;
    }

    hr = _privateKey.CoCreateInstance(__uuidof(CX509PrivateKey), NULL, CLSCTX_INPROC_SERVER);
    if (FAILED(hr)){
        return -1;
    }
    CComBSTR friendlyName("Certificate");
    _privateKey->put_FriendlyName(friendlyName);
    CComBSTR description("Certificate for my Server");
    _privateKey->put_Description(description);
    _privateKey->put_Length(2048);
    _privateKey->put_KeySpec(X509KeySpec::XCN_AT_SIGNATURE);
    _privateKey->put_KeyUsage(X509PrivateKeyUsageFlags::XCN_NCRYPT_ALLOW_ALL_USAGES);
    CComVariant _isMachineContext(true);
    _privateKey->put_MachineContext(_isMachineContext.boolVal);
    _privateKey->put_CspInformations(_cspInformations);

    hr = _privateKey->Create();
    _privateKey->Verify(X509PrivateKeyVerify::VerifyAllowUI);
    if (FAILED(hr)){
        return -1;
    }
    hr = _csrquestpkcs10.CoCreateInstance(__uuidof(CX509CertificateRequestPkcs10), NULL, CLSCTX_INPROC_SERVER);
    CComBSTR _template("");
    hr = _csrquestpkcs10->InitializeFromPrivateKey(X509CertificateEnrollmentContext::ContextMachine, _privateKey, _template);

    if (FAILED(hr)){
        return -1;
    }
    hr = _extensionKeyUsage.CoCreateInstance(__uuidof(CX509ExtensionKeyUsage), NULL, CLSCTX_INPROC_SERVER);


    hr = _extensionKeyUsage->InitializeEncode((X509KeyUsageFlags)(X509KeyUsageFlags::XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE
        |
        X509KeyUsageFlags::XCN_CERT_NON_REPUDIATION_KEY_USAGE |
        X509KeyUsageFlags::XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE |
        X509KeyUsageFlags::XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE)
        );
    CComPtr<IX509Extensions> _extensions;

    hr = _csrquestpkcs10->get_X509Extensions(&_extensions);
    if (FAILED(hr)){
        return -1;
    }
    hr = _extensions->Add(_extensionKeyUsage);

    CComPtr<IObjectId > _objectId;
    CComPtr<IObjectIds > _objectIds;

    hr = _objectId.CoCreateInstance(__uuidof(CObjectId), NULL, CLSCTX_INPROC_SERVER);
    CComBSTR _objId("1.3.6.1.5.5.7.3.2");
    _objectId->InitializeFromValue(_objId);

    _objectIds.CoCreateInstance(__uuidof(CObjectIds), NULL, CLSCTX_INPROC_SERVER);
    _objectIds->Add(_objectId);

    hr = _enhancedKeyUsageExtension.CoCreateInstance(__uuidof(CX509ExtensionEnhancedKeyUsage), NULL, CLSCTX_INPROC_SERVER);
    _enhancedKeyUsageExtension->InitializeEncode(_objectIds);
    _extensions->Add(_enhancedKeyUsageExtension);


    hr = _distinguishName.CoCreateInstance(__uuidof(CX500DistinguishedName), NULL, CLSCTX_INPROC_SERVER);
    std::string sdn = "CN=AKDEVELOPEMNT,OU=D,O=P,L=PUNE,S=HY,C=IN";
    CComBSTR _dn(sdn.c_str());
    hr = _distinguishName->Encode(_dn, X500NameFlags::XCN_CERT_X500_NAME_STR);
    if (FAILED(hr)){
        return -1;
    }
    hr = _csrquestpkcs10->put_Subject(_distinguishName);
    if (FAILED(hr)){
        return -1;
    }


    hr = _enroll.CoCreateInstance(__uuidof(CX509Enrollment), NULL, CLSCTX_INPROC_SERVER);

    if (FAILED(hr)){
        //PLog::instance()->Log(PLDEBUG, "[%s:%d] Encoding csr failed. %d, %d", __FUNCTION__, __LINE__, GetLastError(), hr);
        return -1;
    }

    hr = _enroll->InitializeFromRequest(_csrquestpkcs10);
    if (FAILED(hr)){
        return -1;
    }
    CComBSTR _request;
    hr = _enroll->CreateRequest(EncodingType::XCN_CRYPT_STRING_BASE64_ANY, &_request);      // NEVER RETURNED S_OK, 
    if (FAILED(hr)){
        _com_error er(hr);
        std::wstring error = er.ErrorMessage();
        wprintf("%s", error.c_str());                   // NEVER 
        return -1;
    }

已解决:

由于某些原因,XCN_CRYPT_STRING_BASE64_ANY不是IX509Enrollment::CreateRequest的有效参数。我把它改成了XCN_CRYPT_STRING_BASE64,一切正常

EN

回答 1

Stack Overflow用户

发布于 2018-11-02 14:51:22

由于某些原因,XCN_CRYPT_STRING_BASE64_ANY不是IX509Enrollment::CreateRequest的有效参数。我把它改成了XCN_CRYPT_STRING_BASE64,一切正常

尽管MSDN没有提供XCN_CRYPT_STRING_BASE64_ANY为什么是无效参数的文档,但我猜测XCN_CRYPT_STRING_BASE64_ANY是用于安装响应的,因为它是标志的组合

在创建CSR时,它需要特定的输出类型。XCN_CRYPT_STRING_BASE64或XCN_CRYPT_STRING_BASE64_HEADER

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52946884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档