我正在尝试使用Powershell从Microsoft CA中提取X509证书扩展信息。这是概念证明,比什么都重要。
我已经使用CertificateAuthority.View
COM对象访问CA数据库,然后使用EnumCertViewExtension(0)
枚举扩展表中的每一行以便访问列。我正在使用GetValue(PROTOTYPE_BINARY,CV_OUT_BASE)
提取列值,该列值将扩展的值作为Base64编码的字符串返回。
以上所述可以使我可以使用System.Security.Cryptography.AsnEncodedData
对此Base64数据进行解码,如下面示例的第一部分所示。此方法的缺点是,每个分配点仅将值作为单个字符串返回(与certutil.exe
实用程序类似的格式),因此提取URL将涉及使用正则表达式或类似方法对该字符串进行进一步解析。
我的另一种想法是尝试使用CertificateAuthority.EncodeCRLDistInfo
解码数据,因为我已经成功地将其他扩展名和COM对象转换为XML和/或JSON,以便以后进行操作。>
但是,此特定选项会产生奇怪的结果。似乎可以完全解码数组中的第一个Base64字符串,但无法解码其他三个字符串。
下面的MCV示例显示了这一点。
# These are the raw Base64 encoded values for the CRL Distribution Point extension as extracted
# from the CA's Db by enumerating CertificateAuthority.View.1
$cdpArr = @(
"MD4wPKA6oDiGNmh0dHA6Ly9wa2kud2luZG93cy50ZXN0L2NkcC9XaW5UZXN0LUlzc3VpbmctQ0EyKDEpLmNybA==",
"MDswOaA3oDWGM2h0dHA6Ly9wa2kud2luZG93cy50ZXN0L2NkcC9XaW5UZXN0LUlzc3VpbmctQ0EyLmNybA==",
"MDswOaA3oDWGM2h0dHA6Ly9wa2kud2luZG93cy50ZXN0L2NkcC9XaW5kb3dzVGVzdC1Sb290LUNBLmNybA==",
"MDkwN6A1oDOGMWh0dHA6Ly9wa2kud2luZG93cy50ZXN0L2NkcC9XaW5UZXN0LVBvbGljeS1DQS5jcmw="
)
# The next three lines display all four CRL Distribution Points, so the input data must be good.
Foreach ($cdp in $cdpArr) {
$cdpASN = New-Object System.Security.Cryptography.AsnEncodedData("2.5.29.31",[convert]::FromBase64String($cdp))
$cdpASN.format($true)
}
# The following only displays one CRL Distribution Point URL
Foreach ($cdp in $cdpArr) {
$cdpObj = new-object -ComObject CertificateAuthority.EncodeCRLDistInfo
$cdpASN = New-Object System.Security.Cryptography.AsnEncodedData("2.5.29.31",[convert]::FromBase64String($cdp))
$bString = ([system.text.encoding]::Unicode).GetString($cdpASN.RawData)
$cdpObj.Decode($bString)
For ($i=0; $i -lt $cdpObj.GetDistPointCount(); $i++){
For ($j=0; $j -lt $cdpObj.GetNameCount($i); $j++) {
"CDP {0}, Name {1}, Choice {2}, URL {3}" -f $i, $j, $cdpObj.GetNameChoice($i,$j), $cdpObj.GetName($i,$j)
}
}
Remove-Variable cdpASN, cdpObj # just in-case something lingers
}
第一部分返回以下内容,其中显示了所有四个分发点均已成功解码,但不幸的是显示为四个字符串:
[1]CRL Distribution Point
Distribution Point Name:
Full Name:
URL=http://pki.windows.test/cdp/WinTest-Issuing-CA2(1).crl
[1]CRL Distribution Point
Distribution Point Name:
Full Name:
URL=http://pki.windows.test/cdp/WinTest-Issuing-CA2.crl
[1]CRL Distribution Point
Distribution Point Name:
Full Name:
URL=http://pki.windows.test/cdp/WindowsTest-Root-CA.crl
[1]CRL Distribution Point
Distribution Point Name:
Full Name:
URL=http://pki.windows.test/cdp/WinTest-Policy-CA.crl
第二部分返回以下内容,显示第一个分发点URL,但不显示任何后续URL。
CDP 0, Name 0, Choice 7, URL http://pki.windows.test/cdp/WinTest-Issuing-CA2(1).crl
CDP 0, Name 0, Choice 7, URL
CDP 0, Name 0, Choice 7, URL
CDP 0, Name 0, Choice 7, URL
如果我重新排列数组中的顺序,则完全成功的解码将随之移动-即,如上所示,数组中的第一个字符串始终完全解码,而不论其位置如何,而其他三个字符串则无法显示URL。 / p>
最初的想法表明Base64字符串存在问题-但是它们都可以使用第一种方法完全解码,从而排除了这种情况。
命中列表中的下一个将是[system.text.encoding]::Unicode
周围的字符串转换,但是在所有情况下,ASN.1必须成功解码,因为GetNameChoice()
方法始终返回7,这也有效地排除了该可能性(也许!)。
这是错误还是我错过了什么?