Мне нужно связаться с правительственным API. Для этого API требуется цифровой сертификат для выполнения запросов.
Если я выполняю запрос с использованием компонентов Indy (TIdHTTP и TIdSSLIOHandlerSocketOpenSSL), я получаю следующее исключение:
"EIdOSSLUnderlyingCryptoError with message: error: 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 файлы были сгенерированы из .PFX с использованием OpenSSL (1.1. 1d), используя следующие команды:
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;