Пошкодження Powershell Invoke-WebRequest з захищеним каналом SSL / TLS


253

Я намагаюся виконати цю команду shellhell

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

і я отримую цю помилку. "Invoke-WebRequest: Запит перервано: Не вдалося створити захищений канал SSL / TLS." Здається, що https-запити спрацьовують (" https://google.com "), але не цей питання. Як змусити це працювати або використовувати іншу команду shellhell для читання вмісту сторінки?


Відповіді:


535

спробуйте скористатися цим

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri https://apod.nasa.gov/apod/

48
За замовчуванням powershell використовує TLS 1.0, для безпеки сайту потрібен TLS 1.2
Chandan Rai

3
Ах, як ти визначив версію веб-сайту TLS?
hewstone

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 є оригінал (мінус редагування SO), так що це відбувається в кожному сеансі, який я починаю зараз. Це не зовсім надійно, оскільки все-таки є деякі сайти, які просто не вдається, але я, безумовно, бачу це питання набагато рідше.


7
Якщо вам потрібно зайти на сайт, який використовує SSLv3, тоді вам захочеться [Net.ServicePointManager]::SecurityProtocol = "Tls12, Tls11, Tls, Ssl3". Пам’ятайте, що SSLv3 та TLSv1.0 застаріли через POODLE, тому використовуйте на свій страх і ризик.
jordanbtucker

Хіба немає способу використовувати відображення, щоб просто дозволити всі типи 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 стороннім стороною), здається, не є.

Сподіваюся, що це комусь допоможе.


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'

0

Я не з'ясував причину, але .pfxдля мене працює перевстановлення сертифіката (як у поточного користувача, так і на локальній машині).


який .pfx ви перевстановили?
Не повернено

@NoRefundsNoReturns Файл сертифіката, який ви хочете використовувати для надсилання запиту.
Спенсер

Мені все ще не зрозуміло, як це стосується питання.
Без повернення

@NoRefundsNoReturns Коли я Invoke-WebRequestлокально, він працює спочатку, але пізніше вийде з ладу. Здається, іноді він більше не може прочитати сертифікат (я не знаю механізму, який знаходиться за ним. Можливо, це налаштування, контрольоване компанією). Але перевстановлення cert працює в цьому випадку.
Спенсер

Якщо ви втрачаєте приватний ключ для сертифіката, який, безумовно, може зробити cert непридатним, але я сумніваюся, що тут проблема. Якщо ви втрачаєте ключ, то вам потрібно переконатися, що ви зберігаєте приватний ключ і позначаєте його стійким. Задайте нове запитання, чи це так, що відбувається.
Не повернено
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.