【问题标题】:Trying to create certificate request from existing public key (programmatically)尝试从现有公钥创建证书请求(以编程方式)
【发布时间】:2015-01-16 15:08:31
【问题描述】:

我正在尝试从现有公钥以编程方式创建证书请求。但我得到一个“请求的属性值为空。(来自 HRESULT 的异常:0x80094004)”异常。 这是我的代码:

    private static string CreateCertRequestMessage(string encodedPublicKeyInfo)
    {
        CObjectId objAlg = new CObjectId();
        objAlg.InitializeFromAlgorithmName(
            ObjectIdGroupId.XCN_CRYPT_PUBKEY_ALG_OID_GROUP_ID, 
            ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, 
            AlgorithmFlags.AlgorithmFlagsNone, 
            "RSA");

        CX509PublicKey objPublicKey = new CX509PublicKey();
        objPublicKey.Initialize(objAlg, encodedPublicKeyInfo, "", EncodingType.XCN_CRYPT_STRING_HEX);
        Console.WriteLine(objPublicKey.Algorithm.FriendlyName);
        Console.WriteLine(objPublicKey.Algorithm.Value);
        Console.WriteLine(objPublicKey.Length);
        Console.WriteLine(objPublicKey.EncodedKey);

        var objPkcs10 = new CX509CertificateRequestCertificate();

        objPkcs10.InitializeFromPublicKey(
            X509CertificateEnrollmentContext.ContextUser,
            objPublicKey,
            string.Empty);


        var objExtensionKeyUsage = new CX509ExtensionKeyUsage();
        objExtensionKeyUsage.InitializeEncode(
            CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE |
            CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_NON_REPUDIATION_KEY_USAGE |
            CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE |
            CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE);
        objPkcs10.X509Extensions.Add((CX509Extension)objExtensionKeyUsage);

        var objObjectId = new CObjectId();
        var objObjectIds = new CObjectIds();
        var objX509ExtensionEnhancedKeyUsage = new CX509ExtensionEnhancedKeyUsage();
        objObjectId.InitializeFromValue("1.3.6.1.5.5.7.3.2");
        objObjectIds.Add(objObjectId);
        objX509ExtensionEnhancedKeyUsage.InitializeEncode(objObjectIds);
        objPkcs10.X509Extensions.Add((CX509Extension)objX509ExtensionEnhancedKeyUsage);

        string templateName = "MHM Template";
        CX509ExtensionTemplateName template = new CX509ExtensionTemplateName();
        template.InitializeEncode(templateName);
        objPkcs10.X509Extensions.Add((CX509Extension)template);

        var objDN = new CX500DistinguishedName();
        var subjectName = "CN = shaunxu.me, OU = ADCS, O = Blog, L = Beijng, S = Beijing, C = CN";
        objDN.Encode(subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE);
        objPkcs10.Subject = objDN;

        CObjectId objHash = new CObjectId();
        objHash.InitializeFromAlgorithmName(
            ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, 
            ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, 
            AlgorithmFlags.AlgorithmFlagsNone, 
            "SHA1");
        objPkcs10.HashAlgorithm = objHash;

        var objEnroll = new CX509Enrollment();
        objEnroll.InitializeFromRequest(objPkcs10);

        var strRequest = objEnroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64);
        return strRequest;
    }

我成功地从私钥创建了请求。 但我需要从公钥创建请求。 请帮我。我到底在这里想念什么。

提前致谢

【问题讨论】:

    标签: c# pki certenroll


    【解决方案1】:

    公钥证书的目的是确认密钥对(私钥和公钥)的所有权。这意味着,当我向另一方出示带有我姓名的证书时,证书颁发机构会确认(通过签署证书)该密钥对实际上属于我。特别是,这意味着我“拥有” private 密钥。 (在这种情况下,所有权意味着我知道,但没有其他人知道。)

    为了确认这一点,证书颁发机构必须确保我拥有私钥。因此,任何认证过程都必须在某些时候涉及私钥。我不会泄露私钥,但至少我必须在质询/响应交换中使用它。公钥用于验证我的响应的有效性,因此证书颁发机构知道我拥有私钥。

    换个角度看。公钥是公开的。拥有一个确认我是公钥的“所有者”的证书有什么用?每个人都知道,你不能“拥有”公钥。

    【讨论】:

    • 感谢您的快速响应。但问题是,我没有私钥也没有生成它。密钥的生成发生在其他公司的智能卡上。他们通过 Web 服务向我发送参数和公钥,以便生成证书并将其返回给他们。我们公司拥有CA(PKI系统)。要求是我们这边生成的证书请求。在这种情况下我该怎么办?
    • 也许其他公司会用我们的注册证书(我们的 CA 生成的)签署公钥?我们会给他们我们的注册证书 pfx 并在我们这边进行验证,这可能吗?
    • 由于您已经通过安全通道获得了有关公钥的信息(我想),因此不需要额外的过程来建立密钥所有权。 - PKCS#10 规范说"Note 2 - The signature on the certification request prevents an entity from requesting a certificate with another party's public key."。所以也许你所缺少的只是请求本身的签名?当然,这需要其他公司提供。
    • 再次感谢您的快速响应。那么我究竟需要做什么才能生成请求。因为当前代码抛出了上述异常。也许您可以提供一个代码示例或确切地告诉我我缺少什么以生成请求
    • 查看文档here。它说“您可以调用 RawDataToBeSigned 属性来检索未签名的 CertificationRequestInfo 对象。”你必须得到智能卡的签名,然后将数据提供给 PKCS#10 对象。 (我不知道这样做的技术细节。) RawData 属性最终必须包含签名的请求数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 2014-05-17
    • 2017-05-14
    • 1970-01-01
    • 2010-10-23
    • 2020-09-15
    • 1970-01-01
    相关资源
    最近更新 更多