簡體   English   中英

如何使用PowerShell從網站下載SSL證書?

[英]How to download the SSL certificate from a website using PowerShell?

我想使用PowerShell從https://www.outlook.com下載SSL證書。 可能嗎? 有人能幫助我嗎?

分享更多知識:-)

$webRequest = [Net.WebRequest]::Create("https://www.outlook.com")
try { $webRequest.GetResponse() } catch {}
$cert = $webRequest.ServicePoint.Certificate
$bytes = $cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert)
set-content -value $bytes -encoding byte -path "$pwd\Outlook.Com.cer"

我的同事Michael J. Lyons和我分享了這個。

您應該能夠通過使用HttpWebRequest對象上的ServicePoint屬性來獲取公鑰。 一旦我們向相關網站發出http請求,就會填充這些必要的信息。

如果請求發送到具有不受信任證書的站點,則GetResponse方法將引發異常,但是, ServicePoint仍將包含Certificate因此我們希望確保在狀態為信任失敗時忽略WebException

所以類似下面這樣的東西應該有效:

function Get-PublicKey
{
    [OutputType([byte[]])]
    PARAM (
        [Uri]$Uri
    )

    if (-Not ($uri.Scheme -eq "https"))
    {
        Write-Error "You can only get keys for https addresses"
        return
    }

    $request = [System.Net.HttpWebRequest]::Create($uri)

    try
    {
        #Make the request but ignore (dispose it) the response, since we only care about the service point
        $request.GetResponse().Dispose()
    }
    catch [System.Net.WebException]
    {
        if ($_.Exception.Status -eq [System.Net.WebExceptionStatus]::TrustFailure)
        {
            #We ignore trust failures, since we only want the certificate, and the service point is still populated at this point
        }
        else
        {
            #Let other exceptions bubble up, or write-error the exception and return from this method
            throw
        }
    }

    #The ServicePoint object should now contain the Certificate for the site.
    $servicePoint = $request.ServicePoint
    $key = $servicePoint.Certificate.GetPublicKey()
    Write-Output $key
}

Get-PublicKey -Uri "https://www.bing.com"
Get-PublicKey -Uri "https://www.facebook.com"

如果要多次調用該方法,並且某些方法可能具有相同的地址,則可能需要使用ServicePointManager.FindServicePoint(System.Uri)方法來改進該函數,因為如果請求已經過,它將返回緩存版本制作到該網站。 因此,您可以檢查服務點是否已填充信息。 如果沒有,請發出Web請求。 如果有,只需使用已有的信息,為自己保存一個http請求。

來自http://poshcode.org/2521

function Get-WebsiteCertificate {
  [CmdletBinding()]
  param (
    [Parameter(Mandatory=$true)] [System.Uri]
      $Uri,
    [Parameter()] [System.IO.FileInfo]
      $OutputFile,
    [Parameter()] [Switch]
      $UseSystemProxy,  
    [Parameter()] [Switch]
      $UseDefaultCredentials,
    [Parameter()] [Switch]
      $TrustAllCertificates
  )
  try {
    $request = [System.Net.WebRequest]::Create($Uri)
    if ($UseSystemProxy) {
      $request.Proxy = [System.Net.WebRequest]::DefaultWebProxy
    }

    if ($UseSystemProxy -and $UseDefaultCredentials) {
      $request.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
    }

    if ($TrustAllCertificates) {
      # Create a compilation environment
      $Provider=New-Object Microsoft.CSharp.CSharpCodeProvider
      $Compiler=$Provider.CreateCompiler()
      $Params=New-Object System.CodeDom.Compiler.CompilerParameters
      $Params.GenerateExecutable=$False
      $Params.GenerateInMemory=$True
      $Params.IncludeDebugInformation=$False
      $Params.ReferencedAssemblies.Add("System.DLL") > $null
      $TASource=@'
        namespace Local.ToolkitExtensions.Net.CertificatePolicy {
          public class TrustAll : System.Net.ICertificatePolicy {
            public TrustAll() { 
            }
            public bool CheckValidationResult(System.Net.ServicePoint sp,
              System.Security.Cryptography.X509Certificates.X509Certificate cert, 
              System.Net.WebRequest req, int problem) {
              return true;
            }
          }
        }
'@ 
      $TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
      $TAAssembly=$TAResults.CompiledAssembly

      ## We now create an instance of the TrustAll and attach it to the ServicePointManager
      $TrustAll=$TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
      [System.Net.ServicePointManager]::CertificatePolicy=$TrustAll
    }

    $response = $request.GetResponse()
    $servicePoint = $request.ServicePoint
    $certificate = $servicePoint.Certificate

    if ($OutputFile) {
      $certBytes = $certificate.Export(
          [System.Security.Cryptography.X509Certificates.X509ContentType]::Cert
        )
      [System.IO.File]::WriteAllBytes( $OutputFile, $certBytes )
      $OutputFile.Refresh()
      return $OutputFile
    } else {
      return $certificate
    }
  } catch {
    Write-Error "Failed to get website certificate. The error was '$_'."
    return $null
  }

  <#
    .SYNOPSIS
      Retrieves the certificate used by a website.

    .DESCRIPTION
      Retrieves the certificate used by a website. Returns either an object or file.

    .PARAMETER  Uri
      The URL of the website. This should start with https.

    .PARAMETER  OutputFile
      Specifies what file to save the certificate as.

    .PARAMETER  UseSystemProxy
      Whether or not to use the system proxy settings.

    .PARAMETER  UseDefaultCredentials
      Whether or not to use the system logon credentials for the proxy.

    .PARAMETER  TrustAllCertificates
      Ignore certificate errors for certificates that are expired, have a mismatched common name or are self signed.

    .EXAMPLE
      PS C:\> Get-WebsiteCertificate "https://www.gmail.com" -UseSystemProxy -UseDefaultCredentials -TrustAllCertificates -OutputFile C:\gmail.cer

    .INPUTS
      Does not accept pipeline input.

    .OUTPUTS
      System.Security.Cryptography.X509Certificates.X509Certificate, System.IO.FileInfo
  #>
}

function Import-Certificate {
<#
    .SYNOPSIS
        Imports certificate in specified certificate store.

    .DESCRIPTION
        Imports certificate in specified certificate store.

    .PARAMETER  CertFile
        The certificate file to be imported.

    .PARAMETER  StoreNames
        The certificate store(s) in which the certificate should be imported.

    .PARAMETER  LocalMachine
        Using the local machine certificate store to import the certificate

    .PARAMETER  CurrentUser
        Using the current user certificate store to import the certificate

    .PARAMETER  CertPassword
        The password which may be used to protect the certificate file

    .EXAMPLE
        PS C:\> Import-Certificate C:\Temp\myCert.cer

        Imports certificate file myCert.cer into the current users personal store

    .EXAMPLE
        PS C:\> Import-Certificate -CertFile C:\Temp\myCert.cer -StoreNames my

        Imports certificate file myCert.cer into the current users personal store

    .EXAMPLE
        PS C:\> Import-Certificate -Cert $certificate -StoreNames my -StoreType LocalMachine

        Imports the certificate stored in $certificate into the local machines personal store 

    .EXAMPLE
        PS C:\> Import-Certificate -Cert $certificate -SN my -ST Machine

        Imports the certificate stored in $certificate into the local machines personal store using alias names

    .EXAMPLE
        PS C:\> ls cert:\currentUser\TrustedPublisher | Import-Certificate -ST Machine -SN TrustedPublisher

        Copies the certificates found in current users TrustedPublishers store to local machines TrustedPublisher using alias  

    .INPUTS
        System.String|System.Security.Cryptography.X509Certificates.X509Certificate2, System.String, System.String

    .OUTPUTS
        NA

    .NOTES
        NAME:      Import-Certificate
        AUTHOR:    Patrick Sczepanksi (Original anti121)
        VERSION:   20110502
        #Requires -Version 2.0
    .LINK
        http://poshcode.org/2643
        http://poshcode.org/1937 (Link to original script)

#>

    [CmdletBinding()]
    param
    (
        [Parameter(ValueFromPipeline=$true,Mandatory=$true, Position=0, ParameterSetName="CertFile")]
        [System.IO.FileInfo]
        $CertFile,

        [Parameter(ValueFromPipeline=$true,Mandatory=$true, Position=0, ParameterSetName="Cert")]
        [System.Security.Cryptography.X509Certificates.X509Certificate2]
        $Cert,

        [Parameter(Position=1)]
        [Alias("SN")]
        [string[]] $StoreNames = "My",

        [Parameter(Position=2)]
        [Alias("Type","ST")]
        [ValidateSet("LocalMachine","Machine","CurrentUser","User")]
        [string]$StoreType = "CurrentUser",

        [Parameter(Position=3)]
        [Alias("Password","PW")]
        [string] $CertPassword
    )

    begin
    {
        [void][System.Reflection.Assembly]::LoadWithPartialName("System.Security")
    }

    process 
    {
        switch ($pscmdlet.ParameterSetName) {
            "CertFile" {
                try {
                    $Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $($CertFile.FullName),$CertPassword
                }
                catch {   
                    Write-Error ("Error reading '$CertFile': $_ .") -ErrorAction:Continue
                }
            }
            "Cert" {

            }
            default {
                Write-Error "Missing parameter:`nYou need to specify either a certificate or a certificate file name."
            }
        }

        switch -regex ($storeType) {
            "Machine$" { $StoreScope = "LocalMachine" }
            "User$"  { $StoreScope = "CurrentUser" }
        } 

        if ( $Cert ) {
            $StoreNames | ForEach-Object {
                $StoreName = $_
                Write-Verbose " [Import-Certificate] :: $($Cert.Subject) ($($Cert.Thumbprint))"
                Write-Verbose " [Import-Certificate] :: Import into cert:\$StoreScope\$StoreName"

                if (Test-Path "cert:\$StoreScope\$StoreName") {
                    try
                    {
                        $store = New-Object System.Security.Cryptography.X509Certificates.X509Store $StoreName, $StoreScope
                        $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
                        $store.Add($Cert)
                        if ( $CertFile ) {
                            Write-Verbose " [Import-Certificate] :: Successfully added '$CertFile' to 'cert:\$StoreScope\$StoreName'."
                        } else {
                            Write-Verbose " [Import-Certificate] :: Successfully added '$($Cert.Subject) ($($Cert.Thumbprint))' to 'cert:\$StoreScope\$StoreName'."
                        }
                    }
                    catch
                    {
                        Write-Error ("Error adding '$($Cert.Subject) ($($Cert.Thumbprint))' to 'cert:\$StoreScope\$StoreName': $_ .") -ErrorAction:Continue
                    }
                    if ( $store ) {
                        $store.Close()
                    }
                } 
                else {
                    Write-Warning "Certificate store '$StoreName' does not exist. Skipping..."
                }
            }
        } else {
            Write-Warning "No certificates found."
        }
    }

    end { 
        Write-Host "Finished importing certificates." 
    }
}

我成功地使用了這樣的函數:

##Import self-signed certificate
Get-WebsiteCertificate $baseUrl local.cer -trust | Out-Null
Import-Certificate -certfile local.cer -SN Root  | Out-Null

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM