首页 > 解决方案 > 仅 Indy 出现 SSL 错误,不会发生 HTTPRIO

问题描述

我必须与政府 API 通信。此 API 需要数字证书才能发出请求。

如果我使用 Indy 组件(TIdHTTP 和 TIdSSLIOHandlerSocketOpenSSL)发出请求,则会收到以下异常:

“带有消息的 EIdOSSLUnderlyingCryptoError:错误:14094412:SSL 例程:SSL3_READ_BYTES:sslv3 警报错误证书”。

如果我使用 THTTPRIO 或 THTTPReqResp 组件发出请求,则不会发生异常,并且我能够从请求中获取响应。

为什么问题只发生在 Indy 上?什么是可能的解决方案?

我正在按如下方式提出 Indy 请求:

procedure TFrmApp.btnIndyClick(Sender: TObject);
var
  Response: TStringStream;
  Url: string;
begin

  Response := TStringStream.Create('', TEncoding.UTF8);
  Url := 'https://testes.tcm.go.gov.br:8443/passaporte/api/auth/representacoes';
  try
    try

      // HTTPIndy is TIdHTTP
      // OpenSSLIndy is TIdSSLIOHandlerSocketOpenSSL

      HTTPIndy.IOHandler := OpenSSLIndy;

      OpenSSLIndy.SSLOptions.CertFile := 'cert.pem';
      OpenSSLIndy.SSLOptions.RootCertFile := 'cert_nokeys.pem';
      OpenSSLIndy.SSLOptions.KeyFile := 'server.key';

      HTTPIndy.Get(Url, Response);

      { Response handling... }

    except
      on E: Exception do
        MessageDlg('Error: ' + sLineBreak + sLineBreak + E.message, mtError, [mbOK], 0);
    end;
  finally
    Response.Free;
  end;

end;

.PEM 和 .KEY 文件是使用 OpenSSL (1.1.1d) 从 .PFX 生成的,使用以下命令:

openssl pkcs12 -in "MyCert.pfx" -passin pass:MyPass -out "cert.pem" -nodes    

openssl pkcs12 -in "MyCert.pfx" -passin pass:MyPass -out "cert_nokeys.pem" -clcerts -nokeys

openssl pkcs12 -in "MyCert.pfx" -passin pass:MyPass -out "key.pem" -passout pass:MyPass -nocerts

openssl rsa -in "key.pem" -passin pass:MyPass -out "server.key"

使用HTTPRIO的请求,我做的如下:

procedure TFrmApp.btnRIOClick(Sender: TObject);
var
  Response: TStringStream;
  Url: string;
begin

  Response := TStringStream.Create('', TEncoding.UTF8);
  Url := 'https://testes.tcm.go.gov.br:8443/passaporte/api/auth/representacoes';
  try
    try

      // HTTPRIO is THTTPRIO

      HTTPRIO.URL := Url;

      HTTPRIO.HTTPWebNode.Get(Response);

      { Response handling ... }

    except
      on E: Exception do
        MessageDlg('Error: ' + sLineBreak + sLineBreak + E.message, mtError, [mbOK], 0);
    end;
  finally
    Response.Free;
  end;

end;

标签: delphisslopensslcertificateindy

解决方案


推荐阅读