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