解析“证书策略”扩展
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析“证书策略”扩展相关的知识,希望对你有一定的参考价值。
我的应用程序中有证书(X509Certificate2
),我可以枚举所有证书的扩展名。其中一个扩展是证书策略,OID为2.5.29.32。这个扩展应该只是一个OID序列,我需要在那里搜索特定的OID。问题是这个扩展名被编码为DER八位字节串。我怎样才能进入我感兴趣的OID?我是否必须手动解析DER八位字节字符串?我怎样才能做到这一点?
编辑:我将看到Bouncy Castle提供的内容,但我想知道.NET框架中是否有现成的解决方案。框架解析证书和其他DER结构,因此可能内置了DER解码器。
BOUNTY:我找到了一个解决方案,但我正在寻求改进。如果满足以下一个或多个条件,Bounty会转到其他解决方案,按相关性排序:
- 它使用标准的.NET库函数
- 它使用成熟或经过验证的源代码或库,比Bouncy Castle小(我只需要解析,而不是所有其余的)
- 它只是改进了我已经拥有的代码,在我认为值得的事情上
BUMP:Bounty今天到期。如果没有其他人提供答案,它将转到GalacticJello。
我一年前遇到过这个问题。我发现了一个帮助我很多的小型图书馆(site)。这个库用xml转换文件密钥(使用.exe)然后我们可以在C#上读取它。
我不喜欢用XML转换我的密钥。我要求图书馆的开发人员在我的项目中使用开源代码,幸运的是他接受了。所以我建造了一个完全符合我需要的fork。
很长一段时间后,我在Mono项目中找到了另一个实现,可用的here。
一个使用CryptoLib here的助手类,这里有一个例子:
public IRegistryService Connect(String name, RSACryptoServiceProvider privateKey, X509Certificate2 acsCertificate) {
if ((String.IsNullOrEmpty(name)) || (acsCertificate == null) || (privateKey == null))
throw new ArgumentException("....");
if (!String.IsNullOrEmpty(this.Credential.identifier))
throw new ACSLoginFailureException("....");
byte[] challenge = this.acs.getChallenge(name);
byte[] answer = new byte[0];
try {
answer = Crypto.GenerateAnswer(challenge, privateKey, acsCertificate);
}
catch (CryptographicException e) {
throw new ACSLoginFailureException("....", e);
}
bool connect = this.acs.loginByCertificate(name, answer, out this.credential, out leaseTime);
// ...
}
我能够使用extension.Format()
获得字符串表示:
foreach (X509Extension extension in certificate.Extensions)
{
if(extension.Oid.FriendlyName.Equals("Certificate Policies"))
{
Console.WriteLine(extension.Format(true));
}
}
我得到的输出看起来像这样:
[1]Certificate Policy:
Policy Identifier=2.16.356.100.2.3
这正是使用certmgr.msc
工具查看证书时出现的内容。这告诉我CCA India定义的证书类别。例如,这是一个Class 3证书。
如果你想要的只是减少解析ASN.1所需的代码,你可以看看ASN.1 Editor project的LCLib部分。
它是一个简单的ASN.1处理器库。
使用样本DER编码的测试字符串“test1@rsa.com”:
16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d
using (var stm = new MemoryStream(new byte[] { 0x16, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x31, 0x40, 0x72, 0x73, 0x61, 0x2e, 0x63, 0x6f, 0x6d }))
{
Asn1Parser parser = new Asn1Parser();
parser.LoadData(stm);
var decoded = parser.ToString();
}
提供格式化输出:
胶印| LenByte |
======+======+=======+====
0| 13| 1| IA5 STRING : 'test1@rsa.com'
您可以遍历树,并根据需要处理节点。
这就是我做的方式(但也请阅读下面的更新)。 Bouncy Castle用于解析ASN.1 DER。
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Asn1.X509;
string GetMeTheOidThatIWant(byte[] certificate)
{
X509CertificateParser parser = new X509CertificateParser();
X509Certificate cert1 = parser.ReadCertificate(certificate);
X509Extension certPolicies =
cert1.CertificateStructure.TbsCertificate.Extensions.GetExtension(X509Extensions.CertificatePolicies);
DerSequence seq = certPolicies.GetParsedValue() as DerSequence;
foreach (Asn1Encodable seqItem in seq)
{
DerSequence subSeq = seqItem as DerSequence;
if (subSeq == null)
continue;
foreach (Asn1Encodable subSeqItem in subSeq)
{
DerObjectIdentifier oid = subSeqItem as DerObjectIdentifier;
if (oid == null)
continue;
if (ThisIsTheOneIWant(oid))
return oid.Id;
}
}
}
更新:我最近偶然发现了支持证书策略OID(CryptFormatObject)的szOID_CERT_POLICIES
。没试过这个功能,但看起来很有用。 5分钟后,我注意到它正是由Kinjal Dixit在answer中所描述的。
这里的问题是证书策略字段具有非标准格式。其内容不是由IETF RFC定义的,而是由CA浏览器论坛定义的。它用于表示扩展验证证书。
这是来自“www.bankofamerica.com”的字段
序列:ObjectIdentifier:2.5.29.32 certificatePolicies OctetString:(48,59,48,57,6,11,96,134,72,1,134,248,69,1,7,23,6,48,42,48 ,40,6,8,43,6,1,5,5,7,2,1,22,28,104,116,116,112,115,58,47,47,119,119,119,46 ,118,101,114,105,115,105,103,110,46,99,111,109,47,114,112,97)OctetString as ASCII:'0; 09 x06 x0b` x86H x01 86 xf8E X01 X07 X17 X060 * 0( X06 X08 + X06 X01 X05 X05 X07 X02 X01 X16 x1chttps://www.verisign.com/rpa”
这是使用Python库“pyasn1”的小程序转储的,它可以解析DER和PEM格式数据。问题是CertificatePolicies的值是ASN1类型“OctetString”,这意味着它只是ASN1的原始字节。大多数其他字段都是有用的类型,如PrintableText,Integer或Date,但不是这一类。
从1999年开始的RFC2527只是手动挥之不去;有一个地方应该填写这些信息,但事实并非如此。 OpenSSL文档(http://www.openssl.org/docs/apps/x509v3_config.html)说“原始扩展的语法由扩展代码管理:它可以包含多个部分的数据。正确的语法为use由扩展代码本身定义:查看证书策略扩展以获取示例。“ CAB论坛EV证书指南(http://www.cabforum.org/EV_Certificate_Guidelines.pdf)定义了该字段中的内容(请参阅附录B),但请参阅RFC3280了解格式。 RFC3280说“证书策略扩展包含一个或多个策略信息术语的序列,每个术语由一个对象标识符(OID)和可选的限定符组成。可选的限定符,可能存在,不会改变定义政策。”所以它应该是包含OID和“可选限定符”的ASN1项目序列。但这不是EV证书实际包含的内容。
至于EV证书允许的OID,没有公开的官方列表。 CA浏览器论坛有一个与其成员共享的私有列表。但在维基百科中寻找一个非官方的。
稍后我弄清楚格式。
以上是关于解析“证书策略”扩展的主要内容,如果未能解决你的问题,请参考以下文章
getSupportFragmentManager() 在活动扩展片段中未定义
无法解析片段中的 ViewModelProvider 构造?
Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段