Новые подробности добавлены под исходным кодом.
Возникла проблема с Delphi, когда интернет-код работает на Win 10, но не на Win 7. Я пытаюсь подключить небольшой проект для их подключения.ком (HIBP).Win 7 возвращает «Ошибка получения сертификата сервера».
Чтобы попытаться исправить проблему Win 7, я добавил OnValidateServerCertificate как в TNetHTTPRequest, так и в TNetHTTPClient.И в Win 10, и в Win 7 OnValidateServerCertificate, похоже, не вызывается.
Я протестировал на 2 компьютерах с Win 10 и 2 компьютерах с Win 7, такие же результаты.1) Почему Win 7 возвращает «Ошибка получения сертификата сервера?2) Почему OnValidateServerCertificate не вызывается на Win 10 или Win 7?
Спасибо за любую помощь!
unit MainUnt;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Net.URLClient,
System.Net.HttpClientComponent,
System.Net.HttpClient;
type
TForm9 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
function HIBPGetRangeResults( const AFirst5CharHashStr: String;
out ARangeResultsStr: String;
out AErrStr: String ): Boolean; inline;
procedure OnValidateServerCertificate( const Sender: TObject;
const ARequest: TURLRequest;
const Certificate: TCertificate;
var Accepted: Boolean );
end;
var
Form9: TForm9;
implementation
{$R *.dfm}
//SHA1( Pa$$word ): 775440A2B268C2F58A9A61B10CC10125703B3015
procedure TForm9.Button1Click(Sender: TObject);
var
TmpErrStr: String;
TmpResultsStr: String;
begin
//HIBP Range wants only the first 5 charactsers so search is anonymous.
if HIBPGetRangeResults( '77544', TmpResultsStr, TmpErrStr ) then
ShowMessage( TmpResultsStr )
else
ShowMessage( TmpErrStr );
end;
function TForm9.HIBPGetRangeResults( const AFirst5CharHashStr: String;
out ARangeResultsStr, AErrStr: String):
Boolean;
const
//GET https://api.pwnedpasswords.com/range/{first 5 hash chars}
//I don't know of another site at this point that works on Win 10, but
fails on Win 7.
kServiceNameStr = 'https://api.pwnedpasswords.com/range/';
var
TmpNetHTTPRequest: TNetHTTPRequest;
TmpNetHTTPClient: TNetHTTPClient;
TmpIHTTPResponse: IHTTPResponse;
begin
Result := False;
try
TmpNetHTTPRequest := TNetHTTPRequest.Create( Nil );
TmpNetHTTPClient := TNetHTTPClient.Create( Nil );
try
TmpNetHTTPClient.OnValidateServerCertificate :=
OnValidateServerCertificate;
TmpNetHTTPClient.ConnectionTimeout := 3000;
TmpNetHTTPClient.ResponseTimeout := 3000;
TmpNetHTTPClient.UserAgent := 'Testing'; //HIBP wants User Agent
filled.
TmpNetHTTPRequest.OnValidateServerCertificate :=
OnValidateServerCertificate;
TmpNetHTTPRequest.ConnectionTimeout := 3000;
TmpNetHTTPRequest.Client := TmpNetHTTPClient;
TmpNetHTTPRequest.URL := kServiceNameStr + AFirst5CharHashStr;
TmpIHTTPResponse := TmpNetHTTPRequest.Execute;
if TmpIHTTPResponse.StatusCode=200 then
begin
ARangeResultsStr := TmpIHTTPResponse.ContentAsString;
Result := True;
end
else
begin
AErrStr := 'Result:' + TmpIHTTPResponse.StatusText;
end;
finally
FreeAndNil( TmpNetHTTPClient );
FreeAndNil( TmpNetHTTPRequest );
end;
except on E: Exception do
AErrStr := E.Message;
end;
end;
procedure TForm9.OnValidateServerCertificate( const Sender: TObject;
const ARequest: TURLRequest;
const Certificate:
TCertificate;
var Accepted: Boolean );
begin
//Just to know it's been called at all.
//Not called in Win 10 or Win 7.
Beep;
end;
end.
Ссылка https://api.pwnedpasswords.com/range/55555 (пример первых 5 хеш-символов)) возвращал ошибку сертификата в IE.Я добавил TLS 1.1 и 1.2 в Свойства обозревателя Win 7, Advanced.Это позволило браузеру работать.
Тем не менее программа не работала.Поэтому я обнаружил в Delphi Source (Berlin) «Ошибка получения сертификата сервера», которая привела к «SNetHttpGetServerCertificate».В System.Net.HttpClient:
procedure THTTPClient.DoValidateServerCertificate(LRequest: THTTPRequest);
...
LServerCertificate := DoGetSSLCertificateFromServer(LRequest);
if LServerCertificate.Expiry = 0 then
raise
ENetHTTPCertificateException.CreateRes(@SNetHttpGetServerCertificate);
Кажется, что это единственное место, из которого можно сгенерировать это исключение.К сожалению, установка точки останова там (даже при включенных отладочных DCU) никогда не была достигнута.
В TWinHTTPClient.DoExecuteRequest существует возможность ServerCertificateInvalid, которую я пропускаю, проходя через нее.Я не могу сказать с моего компьютера с Win 10, запущен ли он на Win 7.
Кроме того, домен, который я вызываю, похоже, использует очень современную конфигурацию SSL: https://www.ssllabs.com/ssltest/analyze.html?d=api.pwnedpasswords.com&s=104.17.70.67.
Возможно, что-то несовместимо с этим конфигом, Delphi (Berlin) и Win 7?
Спасибо за любую помощь!