使用Powershell枚举CertificateAuthority.EncodeCRLDistInfo

时间:2019-04-30 10:41:28

标签: powershell com x509 pki

我正在尝试使用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,这也有效地排除了该可能性(也许!)。

这是错误还是我错过了什么?

0 个答案:

没有答案