【问题标题】:PowerShell HTTPS GET using client certificate from certstorePowerShell HTTPS GET 使用来自 certstore 的客户端证书
【发布时间】:2012-09-28 17:48:20
【问题描述】:

我正在尝试使用客户端证书通过 HTTPS 检查 Web 内容的简单方法。 我有 VBScript,其中定义了客户端证书,跳过了服务器证书并定义了我正在搜索的内容(字符串“运行”)。我的意思是将脚本重写为 PowerShell。

这里是 VBS 代码:

device = "10.10.10.10"
link = "5001/test"
Set Http = CreateObject("WinHttp.WinHttpRequest.5.1")
Http.SetClientCertificate "LOCAL_MACHINE\MY\test"
Http.Option(4) = 256 + 512 + 4096 + 8192 
Http.Open "GET", "https://" & device & ":" & link, false
Http.Send
output = Http.ResponseText
If InStr(1,output,"running") Then
wscript.echo "OK"
Else
wscript.echo "Error"
End If
Set Http = Nothing

这是获取 HTTP 网页内容(但不是 https)的 Powershell 语法:

$page = (New-Object System.Net.WebClient).DownloadString("http://10.10.10.10:5001/test")
"$page"

这是使用 .CRT 文件(但不是来自 CERTSTORE)获取 HTTPS 内容的 Powershell 语法

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::CreateFromCertFile("C:\Cert\test.crt")
$url = "https://10.10.10.10:5001/test"
$web = [System.Net.WebRequest]::Create($url)
$web.ClientCertificates.Add($Cert)

这是我最近尝试获取网络内容。没有成功。

#ignore untrusted certificate
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
#load my client certificate defined by thumbprint
$cert = Get-Childitem cert:\LocalMachine\My\5AA55B7B8D99
#get web contetn
$web = [System.Net.WebRequest]::Create($url)
#use my client certificate
$web.ClientCertificates.Add($Cert)

有什么想法吗? 最好的问候

【问题讨论】:

  • 您不能使用 CRT 文件进行 HTTPS 客户端身份验证。它只包含证书,不包含私钥。
  • 是的,所以这就是使用 certstore 的原因。
  • 所以我有下面的脚本但仍然无法工作。任何想法?最好的问候
  • #ignore untrusted certificate[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}#load my client certificate defined by thumbprint$cert = Get-Childitem cert:\LocalMachine\My\5AA55B7B8D99#get web contetn$web = [System.Net.WebRequest]::Create($url)#use my client certificate$web.ClientCertificates.Add($Cert)
  • 您不应使用评论部分来添加新信息。改为编辑您的问题 - 这大大提高了代码的可读性。

标签: powershell https get certificate


【解决方案1】:

你的这个,但我无法测试它

$device = "10.10.10.10"
$link = "5001/test"
$Http = New-Object 'WinHttp.WinHttpRequest.5.1'
$Http.SetClientCertificate( "LOCAL_MACHINE\MY\test" )
$Http.Option(256 + 512 + 4096 + 8192) # or $Http.Option(4)
$Http.Open("GET", "https://" + $device + ":" + $link, $false)
Http.Send()
$output = Http.ResponseText

【讨论】:

    【解决方案2】:

    我建议使用 .NET 类 X509Store 访问证书。使用Certificates 属性(如下示例),您可以通过指纹找到证书并将其附加到请求中。

    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
    $Store = New-Object System.Security.Cryptography.X509Certificates.X509Store(
            [System.Security.Cryptography.X509Certificates.StoreName]::My, "localmachine")
    $Store.Open("MaxAllowed")
    $Certificate = $Store.Certificates |  Where-Object Thumbprint -Eq "XXXXXXXXXXXXXXXX"
    $Web = [System.Net.WebRequest]::Create($Url)
    $Web.ClientCertificates.Add($Certificate)
    $Response = $Web.GetResponse()
    

    【讨论】:

    • 我建议发布一个不仅仅包含代码块的答案。如果您解释您的解决方案,用户可能会了解更多信息?
    【解决方案3】:

    这对我有用:

    Invoke-RestMethod https://10.10.10.10:5001/test -CertificateThumbprint XXXXXXXXXXXXXXXX 
    

    【讨论】:

    • 对我不起作用,尽管证书在我的个人商店中,但它不接受指纹。
    • 这样够安全吗?
    【解决方案4】:

    当我尝试为 PRTG 创建启用客户端证书的传感器时,这对我有用。您可能想要更改超时值。此外,您还需要捕获异常,以防网站因任何原因无法访问。

    $CertNumber = 证书指纹。

    $CheckURL = 要加载的 URL。

    证书加载和阅读网站

    #*************************************
    #********CERTIFICATE LOADING**********
    #*************************************
    
    # LOAD CERTIFICATE FROM STORE
    $Certificate = Get-ChildItem -Path Cert:\LocalMachine\My\$CertNumber
    # CREATE WEB REQUEST
    $req = [system.Net.HttpWebRequest]::Create($checkURL)
    # ADD CERTS TO WEB REQUEST
    $req.ClientCertificates.AddRange($Certificate)
    
    #*************************************
    #***********READING SITE**************
    #*************************************
    
    #SET TIMEOUT 
    $req.Timeout=10000
    # GET WEB RESPONSE
    $res = $req.GetResponse()
    # GET DATA FROM RESPONSE
    $ResponseStream = $res.GetResponseStream()
    # Create a stream reader and read the stream returning the string value.
    $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream
    # BUILD STRING FROM RESPONSE
    $strHtml = $StreamReader.ReadToEnd()
    

    【讨论】:

      【解决方案5】:

      答案有点晚,但这是我在阅读当前答案后得出的结论。

      您可以使用“Invoke-WebRequest”和 -Certificate 参数。您也可以在 Powershell 中使用“wget”,因为它是“Invoke-WebRequest”的别名

      $cert = Get-ChildItem -Path cert:\LocalMachine\My\5AA55B7B8D99
      $response = wget -Uri "https://10.10.10.10:5001/test" -method "Get" -Certificate $cert
      $response.Content.Contains("running")
      

      【讨论】:

      • 在这种情况下,Get-Item 可以与 Get-ChildItem 互换。
      【解决方案6】:

      一个问题可能是客户端计算机必须信任它发送的证书。因此,如果您尝试发送的客户端证书不是自签名的,则需要将颁发者证书导入机器的受信任根目录中。一旦你有了它,你可以使用System.Security.Cryptography.X509Certificates.X509Certificate2构造函数(而不是CreateFromCertFile方法)添加MachineKeySet标志

      例如,在我的机器上,我有一个 pfx(没有密码,因此第二个参数是 $null),我想发布一些需要客户端证书身份验证的内容:

      [Powershell]

      $content = [System.IO.File]::ReadAllBytes("SomeContentIWantToPOST.json")
      $endpoint = "https://contoso.com/endpoint"
      $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("MySuperPrivateCert.pfx",$null,[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet)
      $request = [System.Net.WebRequest]::Create($endpoint)
      $request.ClientCertificates.Add($Cert)
      $request.Method = "POST"
      $request.ContentLength = $content.Length
      $request.ContentType = "application/json"
      $dataStream = $request.GetRequestStream()
      $dataStream.Write($content, 0, $content.Length)
      $dataStream.Close()
      

      【讨论】:

        猜你喜欢
        • 2017-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-22
        • 2010-12-12
        • 1970-01-01
        • 2016-05-30
        • 1970-01-01
        相关资源
        最近更新 更多