使用.NET和Powershell远程推送PFX证书和私钥

时间:2014-11-03 15:25:22

标签: c# .net powershell x509certificate2

手头的任务是将证书从中央服务器推送到收件人服务器。我能够利用x509certificate2方法来完成证书安装。即使存储标志指示add()方法安装私钥,它也不会将其安装在远程计算机上。在下面的代码中,请相信$CertObj是使用存储标记ExportableMachineKeySetPersistKeySet创建的x509certificate2对象。

Function Import-CertificateObject
{
    Param
    (
        [parameter(mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Computer
    )

    $CertStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList "\\$($Computer)\$Location",$Store
    $CertStore.Open("ReadWrite")
    $CertStore.Add($CertObj)
    $CertStore.Close()

}

使用powershell隔离已安装的证书对象,我可以看到HasPrivateKey属性已设置为true。在服务器上本地检查已安装的证书以及从安装它的远程服务器检查已安装的证书。接下来,如果您从安装了证书的服务器检查PrivateKey属性,则它是空白的。但是,当从安装它的服务器进行检查时,powershell会返回私钥的对象数据。

使用ProcMon我可以看到,当证书正在安装私钥的regkey时,它会在正在远程服务器上执行安装的服务器上执行此操作。我需要.Net在远程计算机上安装证书私钥。我已经阅读了x509certificate2 docs,但它根本没有涉及远程安装,也没有深入解释这些方法的用途。

我希望它像在add()方法之前更改环境变量一样简单,或者我可能从错误的角度完全接近这个。那么如何让它在远程服务器上安装私钥,而不是推送证书的服务器?

2 个答案:

答案 0 :(得分:1)

您无法通过网络移动/复制具有关联私钥的证书。使用您的代码,您只需复制证书的公共部分。私钥保留在源服务器上,不会在任何地方移动/复制。

HasPrivateKey属性是一个附加存储的属性,与私钥的存在有一点关系,并不是确定是否为该证书安装私钥的可靠方法。

使用私钥跨机器复制证书的唯一正确方法是:

  1. 使用以下方法导出证书和附加的私钥:Export(X509ContentType, SecureString)或此:Export(X509ContentType, String)重载。
  2. 将PFX文件复制到目标服务器,并使用these重载之一将带有私钥的证书导入X509Certificate2对象,并使用X509Store对象将其安装到商店。
  3. 但是,请注意,如果在密钥生成或安装过程中私钥未标记为可导出,则您的任务将无法执行,因为私钥受CSP / KSP保护,您将无法从提供程序导出密钥

答案 1 :(得分:0)

这里的解决方案是利用Invoke-Command -ScriptBlock{}在本地执行机器上的代码。