我必须以尊重给定结构的方式添加证书请求(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对象,将OID添加到PKCS10请求中:
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);
然而,我得到了令人费解的错误“文件存在。(HRESULT异常:0x80070050)”在编码请求的过程结束时,我尝试使用不同的智能卡广告,密钥容器都可以,而不是已满。
我的方法是否正确添加此挑战密码扩展名,我该如何解释此错误?
答案 0 :(得分:2)
您获得的错误的答案&#34;该文件存在。 (HRESULT异常:0x80070050)&#34;是因为尝试在已经有密钥的模板上设置密钥。只是评论一下:
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);
它应该有用。
在文章Working with Active Directory Certificate Service via C#中搜索:
似乎我们已经完成了,但是如果我们只是执行它就会抛出一个 我们的例外,说添加一些文件时存在 扩展。
它解释了一切。
来自文章:
异常消息可能有点令人困惑。实际上这是 因为我们定义了证书中定义的内容 模板。如果我们深入研究源代码,我们可以看到异常 我们添加了密钥用法扩展名时发生了。
如果我们回到CA服务器并打开我们的模板 使用,我们可以发现密钥用法已在中定义 模板。这意味着在代码中,或在证书请求中我们 不应再指定它。
因此,我们需要评论添加密钥用法的代码 需要对增强型密钥使用部分进行评论,因为它已被定义 在模板中也是如此。因为我们让请求提供主题 在这里我们仍然可以指定主题信息 请求。生成请求消息的方法就是这样。
答案 1 :(得分:0)
以下是将挑战密码包含在CertEnroll生成的PKCS10中的代码:
private static byte[] getDerBytes(int tag, byte[] data)
{
if (data.Length > byte.MaxValue)
{
throw new NotSupportedException("Support for integers greater than 255 not yet implemented.");
}
var header = new byte[] { (byte)tag, (byte)data.Length };
return header.Concat(data).ToArray();
}
和
public static byte[] EncodePrintableString(string data)
{
var dataBytes = Encoding.ASCII.GetBytes(data);
return getDerBytes(0x13, dataBytes);
}
最后:
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);