添加扩展到证书请求(密码攻击)用C#和CertENrollLib(adding extensions

2019-10-20 13:46发布

我不得不在使得我尊重给定结构的方式添加扩展的证书请求(CSR)。 即这一项

在左边的是我必须为chalenge密码尊重结构,右边的结构,我得到的时候,我只是生成的挑战口令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)。”在过程的编码请求时结束时,我用不同的智能卡的广告尝试密钥容器都行,不饱满。

是我对加入这一挑战密码扩展正确的,我怎么能解释这个错误的方法呢?

Answer 1:

这个问题的答案你所得到的错误“文件存在(从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);

它应该工作。


搜索这个在文章中使用Active Directory证书服务通过C#的工作为:

看来,我们完成了,但如果我们只是执行它会抛出异常给我们,说是增加了一些扩展时,该文件存在。

它说明了一切。


从文章:

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

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

因此,我们需要注释的代码添加密钥使用,还需要我们,因为它已经在模板中定义,也评论的增强型密钥用法部分。 因为我们让请求,由这里提供使用者名称,我们仍然可以指定在请求中的主体的信息。 用于产生请求消息的方法,会是这样。



Answer 2:

下面是代码,包括质询密码成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);
    }

和finnally:

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);


文章来源: adding extensions to a certificate request ( password-challenge ) with C# and CertENrollLib