3

我通过阅读MSDN 了解到 X509 v3 扩展必须是手工制作的。这涉及 CRL、AIA、名称和策略约束、策略映射、私钥使用期限和主题目录属性。

我试图创建一个 CRL 分发点,但结果是垃圾:

    $crlExt = New-Object -ComObject X509Enrollment.CX509Extension
    $crlOid = New-Object -ComObject X509Enrollment.CObjectId
    $crlOid.InitializeFromValue('2.5.29.31')
    $crlValue = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('http://www.test.com'))
    $crlExt.Initialize($crlOid, 0x1, $crlValue)
    $crlExt.Critical = $false

是否有关于如何对以下各项的值进行编码的任何参考?我已经搜遍了,但没有运气。

  • 权威信息访问
  • Crl分布点
  • 最新鲜的CRL
  • 名称约束
  • 政策约束
  • 策略映射
  • PrivateKeyUsagePeriod
  • 主题目录属性

请注意,这是关于 Windows 中的 certenroll com 接口。openssl 在这里不适用。

4

1 回答 1

0

我刚刚在 C# 中遇到了同样的问题,试图通过 CertEnroll.dll 生成带有 CDP(CRL 分发点)扩展的证书

我可以完成这项工作的唯一方法是在字节级别手工制作扩展,尽管我没有找到任何关于字节应该如何排序或某些字节含义的文档。为了弄清楚我在 Linux 中使用 OpenSSL 生成了一些证书并检查了 C# 中的原始字节(在X509Certificate2 类中加载证书并查看Extensions属性。X509Extension 类有一个RawData属性)。

您应该能够将我的代码转换为 PowerShell,所以我最终得到:

var urisStr = new string[]
{
    "http://pki.example.com/list.crl"
};
var uris = urisStr.Select(u => Encoding.UTF8.GetBytes(u));
var zero = new byte[] { 48 }; //"0", delimiter ?
var nbsp = new byte[] { 160 }; //" ", separator ?
var dagger = new byte[] { 134 }; //"dagger", separator ?

var zeroSize = zero.Length + 1;
var nbspSize = nbsp.Length + 1;
var daggerSize = dagger.Length + 1;

var col = new List<byte>();
col.AddRange(zero); //delimiter
int totalBytes = uris.Sum(u => u.Length);
totalBytes += (zeroSize + (nbspSize * 2) + daggerSize) * uris.Count();
col.Add((byte)totalBytes); //size of everything it contains

foreach (var uri in uris)
{
    var uriSize = uri.Length;
    col.AddRange(zero); //delimiter
    col.Add((byte)(nbspSize + nbspSize + uriSize + daggerSize)); //size of everything it contains
    col.AddRange(nbsp);
    col.Add((byte)(nbspSize + uriSize + daggerSize)); //size of everything it contains
    col.AddRange(nbsp);
    col.Add((byte)(uriSize + daggerSize)); //size of everything it contains
    col.AddRange(dagger); //separator ?
    col.Add((byte)uriSize);
    col.AddRange(uri);
}
var bytes = col.ToArray();
var base64 = Convert.ToBase64String(bytes);

var oidCDP = new CObjectId();
oidCDP.InitializeFromName(CERTENROLL_OBJECTID.XCN_OID_CRL_DIST_POINTS);

// There is no specific class to CDPs, so we use the CX509Extension
var crlList = new CX509Extension();
crlList.Initialize(oidCDP, EncodingType.XCN_CRYPT_STRING_BASE64, base64);
certRequest.X509Extensions.Add(crlList);

请注意,我没有找到任何关于我正在生成的字节格式的文档,所以这段代码没有官方依据。它仅基于对工作证书的观察。

于 2016-12-16T11:23:22.037 回答