如何使用PowerShell下载自签名Web服务器证书?
在PowerShell中不使用OpenSSL获取自签名证书
原代码无法获取自签名证书的核心原因是:SslStream.AuthenticateAsClient()默认会校验证书的信任链,自签名证书因无受信任根CA背书,会导致TLS握手失败(有时错误信息会表现为连接超时)。
你可以通过自定义证书验证回调绕过信任校验,同时成功获取远程证书。修改后的函数如下:
function Get-RemoteCertificate { [CmdletBinding()] [OutputType([System.Security.Cryptography.X509Certificates.X509Certificate2])] param ( [Parameter(Mandatory, ValueFromPipeline)] [ValidateNotNull()] [Uri]$Uri ) process { $tcpClient = $null $sslStream = $null try { # 建立TCP连接 $tcpClient = [System.Net.Sockets.TcpClient]::new($Uri.Host, $Uri.Port) $sslStream = [System.Net.Security.SslStream]::new( $tcpClient.GetStream(), $false, [System.Net.Security.RemoteCertificateValidationCallback]{ $true } ) # 执行TLS握手,跳过证书验证 $sslStream.AuthenticateAsClient($Uri.Host) # 返回证书(转换为X509Certificate2以便后续操作) [System.Security.Cryptography.X509Certificates.X509Certificate2]$sslStream.RemoteCertificate } finally { # 确保资源释放 if ($sslStream) { $sslStream.Dispose() } if ($tcpClient) { $tcpClient.Dispose() } } } }
关键修改说明:
- 实例化
SslStream时传入自定义验证回调函数,直接返回$true,表示接受任何证书(包括自签名、过期、域名不匹配的证书)。 - 将输出类型改为
X509Certificate2,它比基础的X509Certificate支持更多操作(比如导出证书文件)。
使用示例:
- 获取目标主机证书:
$cert = Get-RemoteCertificate -Uri "https://your-selfsigned-server:443"
- 导出证书到本地文件:
$cert | Export-Certificate -FilePath "C:\temp\server-cert.cer" -Type CERT
注意事项:
- 此方法仅用于获取证书的场景,不要在实际业务通信中使用跳过证书验证的逻辑,会带来安全风险。
- 若遇到连接超时错误,优先确认目标主机端口是否开放、网络是否可达,再排查证书相关问题。
内容的提问来源于stack exchange,提问作者Dennis
相关产品推荐
相关产品推荐

