X509Store.Open()抛出异常

时间:2015-03-18 04:37:04

标签: powershell certificate x509

为什么$store.Open($openFlags)抛出一个异常,并且有一种比我的"更好的方法来解决问题。使它工作?

<#
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store("Cert:\CurrentUser\My")
$openFlags = [System.Security.Cryptography.X509Certificates.OpenFlags]::MaxAllowed

$store.Open($openFlags) #Exception calling "Open" with "1" argument(s): "The parameter is incorrect.
#>

#Work Around:
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store("Cert:\CurrentUser\My")
$openFlags = [System.Security.Cryptography.X509Certificates.OpenFlags]::MaxAllowed

$startIndexOfStoreName = $store.Name.LastIndexOf("\") + 1
$lengthOfStoreName = $store.Name.Length - $startIndexOfStoreName
$storeNameString = $store.Name.Substring($startIndexOfStoreName, $lengthOfStoreName)
$storeName = [System.Security.Cryptography.X509Certificates.StoreName]$storeNameString
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store($storeName, $store.Location)

$store.Open($openFlags) #No Exception thrown!

更新:好像在使用X509Store(String)构造函数时,不允许有任何斜杠(如果我错了,请更正我)。所以$store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My")有效。

3 个答案:

答案 0 :(得分:1)

使用

定义证书存储区
$store = Get-Item "Cert:\CurrentUser\My"

而不是

$store = New-Object System.Security.Cryptography.X509Certificates.X509Store("Cert:\CurrentUser\My")

说实话,我还在试图找出它的工作原理或方法。

第一种方法返回一个名为&#34; My&#34;的$ store,所以我假设它专门针对商店,你可以用

打开它
$store.Open($openFlags)

第二种方法返回名为&#34; Cert:\ CurrentUser \ My&#34;的$ store。打开方法就会失败。

答案 1 :(得分:1)

我想对此进行评论,因为正如前面已经指出的,在前面的示例中“ .NET Framework的混合和PowerShell Provider的使用”。对我来说,我需要它作为纯.NET的方式来工作,以使证书无需用户计算机上的完整开发环境即可测试一些C#等效代码。

这是我想出的,能起作用的:

$Location = [Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser
$StoreName = [Security.Cryptography.X509Certificates.StoreName]::My
$Store = New-Object System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $StoreName, $Location
$OpenFlags = [System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly
$Store.Open($OpenFlags)
$Store.Certificates

答案 2 :(得分:0)

实际上,你正在混合方法。一个是通过提供商(Cert :),另一个是.Net类型(X509Store)。用于连接到证书库和提取证书详细信息的过程非常不同。

将“Cert:”想象成一个PSDrive(它基本上就是这样)。所以你可以获得-iteitem等,而不需要“打开”商店。在这种思维模式中,证书库位置是文件夹,证书是单个对象:

# List the store locations
gci Cert:\
# List store names in CurrentUser store location
gci Cert:\CurrentUser
# List certs in the My store of CurrentUser store location
gci Cert:\CurrentUser\My | format-list

使用Cert:提供程序的问题是,如果要在远程系统上使用证书,则需要启用远程处理(WinRM),以便“Invoke-Command”。并非每个环境都允许这样。这就是.Net X509Store的用武之地。不知道它与“CurrentUser”的效果如何,但我从来没有关注过这个问题 - 我对“LocalMachine”商店(特别是“我的”)的内容更感兴趣这是系统保存web和auth证书的地方)。修改后的代码段列出了这些证书(从我为查询SharePoint场中的所有服务器而构建的脚本中提取)。

# Change as necessary
$strTarget = $env:computername
$strCertStoreLocation = 'LocalMachine'
$strCertStoreName = 'My'
# Set up store parameters, connect and open store
[System.Security.Cryptography.X509Certificates.StoreLocation]$strStoreLoc = [String]$strCertStoreLocation
[System.Security.Cryptography.X509Certificates.StoreName]$strStoreName = [String]$strCertStoreName
$objCertStore  = New-Object System.Security.Cryptography.X509Certificates.X509Store -ArgumentList "\\$($strTarget)\$($strStoreName)", $strStoreLoc
$objCertStore.Open('ReadOnly')

# List cert details in bulk
$objCertStore.Certificates | Format-List
# List specific props
foreach ($Cert in $objCertStore.Certificates) {
    "Subject: $($Cert.Subject)"
    "Issuer:  $($Cert.Issuer)"
    "Issued:  $($Cert.NotBefore)"
    "Expires: $($Cert.NotAfter)"
    ""
}

有关每个的详细信息,请点击您最喜欢的技术存储库(MSDN,PowerShell.org,Hey Scripting Guy等):)