Сбой Powershell Invoke-WebRequest с защищенным каналом SSL / TLS

255

Я пытаюсь выполнить эту команду powershell

Invoke-WebRequest -Uri https://apod.nasa.gov/apod/

и я получаю эту ошибку. «Invoke-WebRequest: запрос был прерван: не удалось создать безопасный канал SSL / TLS». https запросы работают (" https://google.com "), но не этот вопрос. Как я могу заставить это работать или использовать другую команду powershell для чтения содержимого страницы?

hewstone
источник

Ответы:

538

попробуйте использовать этот

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri https://apod.nasa.gov/apod/
Чандан Рай
источник
48
По умолчанию PowerShell использует TLS 1.0, для безопасности сайта требуется TLS 1.2
Чандан Рай
3
Ах, как вы определили версию сайта TLS?
Хьюстон
16
Попробуйте SSLLabs для определения информации: Отчет SSL: apod.nasa.gov показывает TLS1.1 и TLS1.2
Кристофер Дж. Льюис
1
Есть ли способ сделать это немного более постоянным? Это работает, но, кажется, сбрасывается с каждым окном консоли.
Брэндон
3
@Brandon Измените $env:Profileили, еще лучше, отредактируйте таблицу реестра .
Франклин Ю
166

В бесстыдной попытке украсть несколько голосов, SecurityProtocolэто Enumс [Flags]атрибутом. Так что вы можете сделать это:

[Net.ServicePointManager]::SecurityProtocol = 
  [Net.SecurityProtocolType]::Tls12 -bor `
  [Net.SecurityProtocolType]::Tls11 -bor `
  [Net.SecurityProtocolType]::Tls

Или, поскольку это PowerShell, вы можете позволить ему разобрать строку:

[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"

Тогда вам технически не нужно знать версию TLS.

Я скопировал и вставил это из сценария, который я создал после прочтения этого ответа, потому что я не хотел перебирать все доступные протоколы, чтобы найти тот, который работал. Конечно, вы можете сделать это, если хотите.

Последнее замечание: в моем профиле PowerShell есть исходная (за вычетом правок) заявка, поэтому сейчас я начинаю каждую сессию. Это не совсем надежно, так как есть некоторые сайты, которые просто выходят из строя, но я наверняка вижу это сообщение гораздо реже.

Нет возврата Нет возврата
источник
7
Если вам нужен доступ к сайту, использующему SSLv3, то вам это нужно [Net.ServicePointManager]::SecurityProtocol = "Tls12, Tls11, Tls, Ssl3". Помните, что SSLv3 и TLSv1.0 устарели из-за POODLE, поэтому используйте их на свой страх и риск.
Джорданбакер
Есть ли способ использовать отражение, чтобы просто разрешить все типы Net.SecurityProtocolType? там должно быть
red888
Почему вы хотите разрешить доступ к известным ошибочным протоколам по умолчанию? Несмотря на это, я полагаю, что предстоящий (на момент написания этой статьи) выпуск PowerShell V7 решит эту проблему раз и навсегда, и этот вопрос постепенно исчезнет в своем законном и заслуженном забвении.
Нет возврата, нет возврата,
2

Если, как и я, ничего из вышеперечисленного не работает, возможно, стоит также попробовать использовать только более низкую версию TLS. Я пробовал оба следующих варианта, но, похоже, не решил мою проблему:

[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls

В конце концов, только когда я настроил TLS 1.0 (в частности, удалил 1.1 и 1.2 в коде), это сработало:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls

Локальный сервер (на который пытались это сделать) в порядке с TLS 1.2, хотя удаленный сервер (который был ранее «подтвержден» как отлично для TLS 1.2 третьей стороной), кажется, не подходит.

Надеюсь, это кому-нибудь поможет.

Mark-DG1
источник
1

Меня устраивает...

if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type)
    {
    $certCallback = @"
        using System;
        using System.Net;
        using System.Net.Security;
        using System.Security.Cryptography.X509Certificates;
        public class ServerCertificateValidationCallback
        {
            public static void Ignore()
            {
                if(ServicePointManager.ServerCertificateValidationCallback ==null)
                {
                    ServicePointManager.ServerCertificateValidationCallback += 
                        delegate
                        (
                            Object obj, 
                            X509Certificate certificate, 
                            X509Chain chain, 
                            SslPolicyErrors errors
                        )
                        {
                            return true;
                        };
                }
            }
        }
    "@
        Add-Type $certCallback
     }
    [ServerCertificateValidationCallback]::Ignore()

Invoke-WebRequest -Uri https://apod.nasa.gov/apod/
Гаутам Балусами
источник
1
Этот ответ эффективно отключает проверку безопасности. Хотя это может устранить ошибку, оно открывает поверхность атаки вашего устройства способами, которые многие сочли бы неприемлемыми. Я никогда не использовал бы это на устройстве, которым я владею.
Нет возврата, нет возврата
1

Убедитесь, что вы сначала переключаете SHELL:

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 
RUN Invoke-WebRequest -UseBasicParsing -Uri  'https://github.com/git-for-windows/git/releases/download/v2.25.1.windows.1/Git-2.25.1-64-bit.exe' -OutFile 'outfile.exe'
pixelbits
источник
0

Я не выяснил причину, но переустановка .pfxсертификата (как на текущем пользователе, так и на локальной машине) работает для меня.

спенсер
источник
какой .pfx переустановил?
Нет возврата, нет возврата
@NoRefundsNoReturns Файл сертификата, который вы хотите использовать для отправки запроса.
Спенсер
Мне до сих пор не ясно, как это применимо к вопросу.
Нет возврата
@NoRefundsNoReturns Когда я на Invoke-WebRequestместе, сначала это работает, но позже не получится. Кажется, что иногда он не может прочитать сертификат больше (я не знаю механизм, стоящий за ним. Может быть, это параметр, контролируемый компанией). Но переустановка сертификата работает в этом случае.
Спенсер
Если вы теряете закрытый ключ для сертификата, который может сделать сертификат непригодным для использования, но я сомневаюсь, что проблема здесь. Если вы теряете ключ, вам необходимо убедиться, что вы сохранили закрытый ключ и отметили его как постоянный. Задайте новый вопрос, если это то, что происходит.
Нет возврата нет возврата