Powershell Invoke-WebRequest échoue avec SSL / TLS Secure Channel

255

J'essaie d'exécuter cette commande Powershell

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

et je reçois cette erreur. "Invoke-WebRequest: la demande a été abandonnée: impossible de créer un canal sécurisé SSL / TLS." Les demandes https semblent fonctionner (" https://google.com ") mais pas celle-ci en question. Comment puis-je le faire fonctionner ou utiliser une autre commande powershell pour lire le contenu de la page?

hewstone
la source
2
Voir aussi Default SecurityProtocol dans .NET 4.5 .
Franklin Yu

Réponses:

538

essayez d'utiliser celui-ci

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri https://apod.nasa.gov/apod/
Chandan Rai
la source
48
Par défaut, powershell utilise TLS 1.0, la sécurité du site nécessite TLS 1.2
Chandan Rai
3
Ah, comment avez-vous déterminé la version TLS du site?
hewstone
16
Essayez SSLLabs pour déterminer les informations: Rapport SSL: apod.nasa.gov montre TLS1.1 et TLS1.2
Christopher G. Lewis
1
Y a-t-il un moyen de le faire qui soit un peu plus permanent? Cela fonctionne mais semble se réinitialiser avec chaque fenêtre de console.
Brandon
3
@Brandon Modifiez-le $env:Profile, ou mieux encore, modifiez la table de registre .
Franklin Yu
166

Dans une tentative éhontée de voler des votes, SecurityProtocolc'est un Enumavec l' [Flags]attribut. Vous pouvez donc faire ceci:

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

Ou puisque c'est PowerShell, vous pouvez le laisser analyser une chaîne pour vous:

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

Ensuite, vous n'avez pas besoin techniquement de connaître la version TLS.

J'ai copié et collé cela à partir d'un script que j'ai créé après avoir lu cette réponse parce que je ne voulais pas parcourir tous les protocoles disponibles pour en trouver un qui fonctionnait. Bien sûr, vous pouvez le faire si vous le souhaitez.

Remarque finale - J'ai la déclaration d'origine (moins les modifications SO) dans mon profil PowerShell, donc c'est à chaque session que je commence maintenant. Ce n'est pas totalement infaillible car il y a encore des sites qui échouent mais je vois sûrement le message en question beaucoup moins fréquemment.

Aucun remboursement, aucun retour
la source
7
Si vous devez accéder à un site qui utilise SSLv3, vous le voudrez [Net.ServicePointManager]::SecurityProtocol = "Tls12, Tls11, Tls, Ssl3". N'oubliez pas que SSLv3 et TLSv1.0 sont obsolètes en raison de POODLE, utilisez-les donc à vos propres risques.
jordanbtucker
n'existe-t-il pas un moyen d'utiliser la réflexion pour autoriser uniquement tous les types Net.SecurityProtocolType? il doit y avoir
red888
Pourquoi voulez-vous autoriser l'accès par défaut aux protocoles connus? Quoi qu'il en soit, je pense que la sortie imminente (au moment de la rédaction de ce document) de PowerShell V7 résoudra ce problème une fois pour toutes et cette question disparaîtra lentement dans son oubli légitime et bien mérité.
Aucun remboursement Aucun retour
2

Si, comme moi, rien de ce qui précède ne fonctionne, il peut être intéressant d'essayer spécifiquement une version TLS inférieure seule. J'avais essayé les deux solutions suivantes, mais ne semblait pas résoudre mon problème:

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

Au final, ce n'est que lorsque j'ai ciblé TLS 1.0 (en particulier supprimer 1.1 et 1.2 dans le code) que cela a fonctionné:

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

Le serveur local (sur lequel cela a été tenté) fonctionne bien avec TLS 1.2, bien que le serveur distant (qui était auparavant "confirmé" comme satisfaisant pour TLS 1.2 par un tiers) ne semble pas l'être.

J'espère que cela aide quelqu'un.

Mark-DG1
la source
1

Ça marche pour moi...

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/
Gowtham Balusamy
la source
1
Cette réponse désactive efficacement le contrôle de sécurité. Bien qu'il puisse éliminer l'erreur, il ouvre la surface d'attaque de votre appareil d'une manière que beaucoup jugeraient inacceptable. Je ne l'utiliserais jamais sur un appareil que je possède.
Aucun remboursement Aucun retour
1

Assurez-vous de commuter le SHELL en premier:

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
la source
0

Je n'ai pas compris la raison, mais la réinstallation du .pfxcertificat (à la fois dans l'utilisateur actuel et sur la machine locale) fonctionne pour moi.

Spencer
la source
quel .pfx avez-vous réinstallé?
Aucun remboursement Aucun retour
@NoRefundsNoReturns Le fichier de certificat que vous souhaitez utiliser pour envoyer la demande.
Spencer
Je ne sais toujours pas comment cela s'applique à la question.
Aucun remboursement Aucun retour
@NoRefundsNoReturns Lorsque je Invoke-WebRequestlocalement, cela fonctionne au début mais échouera plus tard. Il semble que parfois, il ne peut plus lire le certificat (je ne connais pas le mécanisme qui le sous-tend. Mais la réinstallation du certificat fonctionne dans ce cas.
Spencer
Si vous perdez la clé privée d'un certificat, cela peut certainement rendre le certificat inutilisable, mais je doute que ce soit le problème ici. Si vous perdez la clé, vous devez vous assurer que vous enregistrez la clé privée et la marquez comme persistante. Posez une nouvelle question si c'est ce qui se passe.
Aucun remboursement Aucun retour