SSL 错误 1409442E 使用 TIdHTTP 通过 HTTPS 下载文件

SSL error 1409442E downloading file over HTTPS with TIdHTTP

我正在使用 Delphi 10.3.3。下面的代码曾经有效,但现在我在尝试通过 HTTPS 下载文件时遇到错误:

Error connecting with SSL error:1409442E:SSL routines:SSL3_READ_BYTES:tlsv1 alert protocol version'

var
  ms : tmemorystream;
  ssl : TIdSSLIOHandlerSocketOpenSSL;
  source,dest : string;
begin
  source := 'https://www.myaddress.com/myfile.zip';
  dest := 'c:\myfile.zip';
  ms := TMemoryStream.Create;
  try
    if pos('https',source) > 0 then
    begin
      ssl := TIdSSLIOHandlerSocketOpenSSL.Create();
      idh.IOHandler := ssl;
    end;
    idhttp1.get(source,ms);
    ms.savetofile(dest);
    result := 'ok';
  finally
    ms.Free;
  end;
end;

TIdSSLIOHandlerSocketOpenSSL uses only TLS v1.0 by default 并且服务器拒绝了。您必须明确允许更新的 TLS 版本:

ssl := TIdSSLIOHandlerSocketOpenSSL.Create();
ssl.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
idh.IOHandler := ssl;

最新版本的 Indy 内置了 https 支持(因此无需创建 SSL IOHandler,Indy 会自动处理)。 此外,在处理文件时,最好使用 TFilestream 而不是 TMemoryStream,因为当您尝试下载不适合内存的文件时会遇到麻烦。

这是给你的 MRE:

program SO60578855;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  idHttp,
  Classes,
  System.SysUtils;

var
  Http : TidHttp;
  Fs   : TFileStream;

begin
  try
   Fs := TFileStream.Create('c:\temp0mb.bin', fmcreate);
   Http := TidHttp.Create(nil);
   try
    Http.Get('https://speed.hetzner.de/100MB.bin', Fs);
   finally
    Http.Free;
    Fs.Free;
   end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
 Readln;
end.