问题
Basically i would like to translate the command curl as with same parameters as its currently in a linux server, but in Powershell, in order to upload a file:
curl -v -T $file -u user:password http://myurl --cacert /opt/keystores/ca_cert.pem
I've found a equivalent command to perform this task: "Invoke-WebRequest" for PowerShell 3.0+, but the problem is I don't know how to call it using a CA Cert file (.pem) and I haven't found any sample in Internet.
Thanks!
回答1:
When you make a TLS
connection in .NET, the peer certificate is validated against a RemoteCertificateValidationCallback function, governed by the ServicePointManager
for the AppDomain in question.
Most examples of how to override the default validation in PowerShell will tell you to just do:
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Don't do that! - it will bypass validation completely.
What you can do, is implement a proper callback function and invoke chain validation manually. Before you do this, you can add certificates not in the machine or user certificate store to the list of chains you can validate against:
$callback = {
param(
$sender,
[System.Security.Cryptography.X509Certificates.X509Certificate]$certificate,
[System.Security.Cryptography.X509Certificates.X509Chain]$chain,
[System.Net.Security.SslPolicyErrors]$sslPolicyErrors
)
# No need to retype this long type name
$CertificateType = [System.Security.Cryptography.X509Certificates.X509Certificate2]
# Read the CA cert from file
$CACert = $CertificateType::CreateFromCertFile("C:\path\to\ca.crt") -as $CertificateType
# Add the CA cert from the file to the ExtraStore on the Chain object
$null = $chain.ChainPolicy.ExtraStore.Add($CACert)
# return the result of chain validation
return $chain.Build($certificate)
}
# Assign your delegate to the ServicePointManager callback
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $callback
# Do your Invoke-WebRequest or WebClient call here
I don't know how to read multiple certificates from a PEM file into a certificate collection, so you'll have to add each ca cert one by one, sorry
回答2:
Your'e looking for Invoke-RestMethod.
It has a Get-PfxCertificate parameter which takes in a PFX certificate from a file. You can convert from pem to PFX file by checking this link
So your code will look something like this:
$cert = Get-PfxCertificate -FilePath c:\path\to\cert.pfx
$userPassB64 = [System.Convert]::ToBase64String([System.Text.ASCIIEncoding]::ASCII.GetBytes("username:password")
Invoke-WebRequest -Uri http://myurl -Method Post -Header @{Authentication "Basic " + $userPassB64} -InFile 'c:\path\to\uploadfile.txt'
Update
As Mathias points out the certificate option in the command is for client certs. The point of the --cacert option is to provide peer validation when the certificate is not in the default certificate bundle that curl uses. See here for related question on what issue this option solves.
I suggest trying the command as is to see if the SSL negotiation succeeds based on the CA's installed on the machine. If SSL negotiation fails then you could try downloading the certificate file from the target site and installing it in the local certificate store. Steps to do this are set out here.
来源:https://stackoverflow.com/questions/36722870/how-to-execute-a-curl-equivalent-in-powershell-invoke-webrequest-using-cacert