使用C#和CertENrollLib向证书请求(密码质询)添加扩展

使用C#和CertENrollLib向证书请求(密码质询)添加扩展,c#,smartcard,certenroll,C#,Smartcard,Certenroll,我必须以尊重给定结构的方式向证书请求(CSR)添加扩展。就是这个 左边是我必须遵守的chalenge密码结构,右边是我从challenge password OID值生成OID对象时得到的结构,然后将所有这些直接嵌入PKCS10请求的扩展列表中: CObjectId cp_oid = new CObjectId(); // OID 1.2.840.113549.1.9.7 // cp_oid.InitializeFromName(CERTENROLL_OBJECTID.XCN_OID_RSA_

我必须以尊重给定结构的方式向证书请求(CSR)添加扩展。就是这个

左边是我必须遵守的chalenge密码结构,右边是我从challenge password OID值生成OID对象时得到的结构,然后将所有这些直接嵌入PKCS10请求的扩展列表中:

CObjectId cp_oid = new CObjectId();

// OID 1.2.840.113549.1.9.7
// cp_oid.InitializeFromName(CERTENROLL_OBJECTID.XCN_OID_RSA_challengePwd);
cp_oid.InitializeFromValue("1.2.840.113549.1.9.7");
CX509Extension extension = new CX509Extension();
string b64__challengePassword=System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(this.challengePassword));

extension.Initialize(cp_oid, EncodingType.XCN_CRYPT_STRING_BASE64_ANY, b64__challengePassword);
_certificateRequest.X509Extensions.Add(extension);
然后创建一个CX509Extension对象,将OID添加到PKCS10请求中:

CObjectId cp_oid = new CObjectId();

// OID 1.2.840.113549.1.9.7
// cp_oid.InitializeFromName(CERTENROLL_OBJECTID.XCN_OID_RSA_challengePwd);
cp_oid.InitializeFromValue("1.2.840.113549.1.9.7");
CX509Extension extension = new CX509Extension();
string b64__challengePassword=System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(this.challengePassword));

extension.Initialize(cp_oid, EncodingType.XCN_CRYPT_STRING_BASE64_ANY, b64__challengePassword);
_certificateRequest.X509Extensions.Add(extension);
由于结构明显不同于我必须获得的(见上图右侧部分),我现在使用更复杂的方法:

_certificateRequest = new CX509CertificateRequestPkcs10();
_certificateRequest.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, (CX509PrivateKey)_privateKey, null);
_certificateRequest.Subject = (CX500DistinguishedName)_subjectName;

CObjectIds cp_oids = new CObjectIds();

CObjectId cp_oid = new CObjectId();
// OID 1.2.840.113549.1.9.7
// cp_oid.InitializeFromName(CERTENROLL_OBJECTID.XCN_OID_RSA_challengePwd);
cp_oid.InitializeFromValue("1.2.840.113549.1.9.7");

CX509Extension _extension = new CX509Extension();

cp_oids.Add(cp_oid);

//now how do I add that oid list to the 1.2.840.113549.1.9.14 OID ?
//I try with CX509ExtensionEnhancedKeyUsage instead of a simple CX509Extension
//which one of all these is the correct extensions?
/*
 *  IX509ExtensionAlternativeNames          Specifies one or more alternative name forms for the subject of a certificate.
    IX509ExtensionAuthorityKeyIdentifier    Represents an AuthorityKeyIdentifier extension.
    IX509ExtensionBasicConstraints          Specifies whether the certificate subject is a certification authority and, if so, the depth of the subordinate certification authority chain.
    IX509ExtensionCertificatePolicies        Represents a collection of policy information terms.
    IX509ExtensionMSApplicationPolicies     Represents a collection of object identifiers that indicate how a certificate can be used by an application.
    IX509ExtensionEnhancedKeyUsage            Represents a collection of object identifiers that identify the intended uses of the public key contained in a certificate.
    IX509ExtensionKeyUsage                    Represents restrictions on the operations that can be performed by the public key contained in the certificate.
    IX509Extensions                         Manages a collection of IX509Extension objects.
    IX509ExtensionSmimeCapabilities            Represents a collection that reports the decryption capabilities of an email recipient to an email sender.
    IX509ExtensionSubjectKeyIdentifier        Represents a SubjectKeyIdentifier extension used to identify a signing certificate.
    IX509ExtensionTemplate                    Represents a CertificateTemplate extension that contains a version 2 template.
    IX509ExtensionTemplateName                Represents a CertificateTemplateName extension that contains a version 1 template.
                 */

CX509ExtensionEnhancedKeyUsage eku = new CX509ExtensionEnhancedKeyUsage();
eku.InitializeEncode(cp_oids);
eku.Critical = false;

CX509AttributeExtensions InitExt = new CX509AttributeExtensions();

//  Add the extension objects into an IX509Extensions collection.
CX509Extensions ext1 = new CX509Extensions();
ext1.Add((CX509Extension)eku);
//  Use the IX509Extensions collection//to initialize an IX509AttributeExtensions object.
CX509AttributeExtensions ext1att = new CX509AttributeExtensions();
ext1att.InitializeEncode(ext1);

//Add the IX509AttributeExtensions object to an IX509Attributes collection.
CX509Attributes att1 = new CX509Attributes();
att1.Add((CX509Attribute)ext1att);

//Use the IX509Attributes collection to initialize an ICryptAttribute object.
CCryptAttribute crypt1 = new CCryptAttribute();
crypt1.InitializeFromValues(att1);

//Initialize a CMC or PKCS #10 request object and retrieve the ICryptAttributes collection.


//Add the ICryptAttribute object to the ICryptAttributes collection for the request.
_certificateRequest.CryptAttributes.Add(crypt1);

//Console.WriteLine("-- encode");
this.status2 = this.status2 + "-- encode <BR>";


try
{
    _certificateRequest.Encode();
}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}

string rawData = _certificateRequest.get_RawData();

Console.WriteLine("data=" + rawData);
\u certificateRequest=新的CX509CertificateRequestSTPKCS10();
_certificateRequest.InitializeFromPrivateKey(X509CertificateRollmentContext.ContextUser,(CX509PrivateKey)\ u privateKey,null);
_certificateRequest.Subject=(CX500 DifferentizedName)\u subjectName;
CObjectIds cp_oids=新的CObjectIds();
CObjectId cp_oid=新的CObjectId();
//OID 1.2.840.113549.1.9.7
//cp_oid.InitializeFromName(CERTENROLL_OBJECTID.XCN_oid_RSA_challengePwd);
cp_oid.初始值FromValue(“1.2.840.113549.1.9.7”);
CX509Extension _extension=新的CX509Extension();
添加(cp_oid);
//现在,如何将该oid列表添加到1.2.840.113549.1.9.14 oid中?
//我尝试使用CX509ExtensionHancedKeyUsage而不是简单的CX509Extension
//以下哪一个是正确的扩展?
/*
*IX509ExtensionAlternativeNames为证书主题指定一个或多个备选名称表单。
IX509ExtensionAuthorityKeyIdentifier表示AuthorityKeyIdentifier扩展。
IX509ExtensionBasicConstraints指定证书主题是否为证书颁发机构,如果是,则指定从属证书颁发机构链的深度。
IX509ExtensionCertificatePolicys表示策略信息术语的集合。
IX509ExtensionsApplicationPolicys表示一组对象标识符,这些标识符指示应用程序如何使用证书。
IX509ExtensionHancedKeyUsage表示一组对象标识符,用于标识证书中包含的公钥的预期用途。
IX509ExtensionKeyUsage表示对证书中包含的公钥可以执行的操作的限制。
IX509Extensions管理IX509Extension对象的集合。
IX509ExtensionSmimeCapabilities表示将电子邮件收件人的解密功能报告给电子邮件发件人的集合。
IX509ExtensionSubjectKeyIdentifier表示用于标识签名证书的SubjectKeyIdentifier扩展。
IX509ExtensionTemplate表示包含版本2模板的CertificateTemplate扩展。
IX509ExtensionTemplateName表示包含版本1模板的CertificateTemplateName扩展。
*/
CX509ExtensionHancedKeyUsage eku=新的CX509ExtensionHancedKeyUsage();
eku.初始化代码(cp_oids);
eku.Critical=false;
CX509AttributeExtensions InitExt=新的CX509AttributeExtensions();
//将扩展对象添加到IX509Extensions集合中。
CX509Extensions ext1=新的CX509Extensions();
ext1.Add((CX509Extension)eku);
//使用IX509Extensions集合//初始化IX509AttributeExtensions对象。
CX509AttributeExtensions ext1att=新的CX509AttributeExtensions();
ext1att.初始化代码(ext1);
//将IX509AttributeExtensions对象添加到IX509Attributes集合。
CX509Attributes att1=新的CX509Attributes();
附件1.添加((CX509Attribute)ext1att);
//使用IX509Attributes集合初始化ICryptAttribute对象。
CCryptAttribute crypt1=新的CCryptAttribute();
crypt1.初始化FROMVALUES(att1);
//初始化CMC或PKCS#10请求对象并检索ICryptAttributes集合。
//将ICryptAttribute对象添加到请求的ICryptAttributes集合中。
_certificateRequest.CryptAttributes.Add(crypt1);
//控制台写入线(“--encode”);
this.status2=this.status2+“--编码
”; 尝试 { _certificateRequest.Encode(); } 捕获(例外情况除外) { Console.WriteLine(例如ToString()); } 字符串rawData=_certificateRequest.get_rawData(); Console.WriteLine(“data=“+rawData”);
然而,我得到了令人费解的错误“文件存在。(HRESULT异常:0x80070050)”在编码请求的过程结束时,我尝试使用不同的智能卡,并且密钥容器正常,没有满


我添加此质询密码扩展名的方法正确吗?我如何解释此错误?

您得到的错误答案“文件存在。(HRESULT异常:0x80070050)”是因为尝试在已具有密钥的模板上设置密钥。请评论一下:

    CX509ExtensionEnhancedKeyUsage eku = new CX509ExtensionEnhancedKeyUsage();
    eku.InitializeEncode(cp_oids);
    eku.Critical = false;

    CX509AttributeExtensions InitExt = new CX509AttributeExtensions();


  //  Add the extension objects into an IX509Extensions collection.
    CX509Extensions ext1= new CX509Extensions();
    ext1.Add((CX509Extension)eku);
它应该会起作用


在文章的中搜索此项,以查找:

似乎我们已经完成了,但如果我们只是执行,它会抛出一个错误 我们例外,说文件存在时添加了一些 扩展

它解释了一切


从文章中:

异常消息可能有点混乱。其实这是 因为我们定义了证书中定义的东西 模板。如果我们深入研究源代码,我们可以看到异常 在添加密钥使用扩展时发生

如果我们回到CA服务器并打开模板,我们将 使用,我们可以发现密钥用法已经在 模板。这意味着在代码或证书请求中 不应再次指定它

因此,我们需要对添加密钥用法的代码进行注释,并且 需要对已定义的增强密钥使用部分进行注释 也在模板中。Bec
CObjectId cp_oid = new CObjectId();

                cp_oid.InitializeFromName(CERTENROLL_OBJECTID.XCN_OID_RSA_challengePwd);
                byte[] b64__challengePassword = EncodePrintableString("password");

                ICryptAttribute ChallengeAttributes = new CCryptAttribute();
                ChallengeAttributes.InitializeFromObjectId(cp_oid);

                CX509Attribute ChallengeAttribute = new CX509Attribute();
                ChallengeAttribute.Initialize(cp_oid, EncodingType.XCN_CRYPT_STRING_BASE64_ANY, 
                                                    Convert.ToBase64String(b64__challengePassword));
                ChallengeAttributes.Values.Add(ChallengeAttribute);

                objPkcs10.CryptAttributes.Add((CCryptAttribute)ChallengeAttributes);