Del*_*Guy 3 delphi ssl-certificate windows-7
在源代码下方添加了新的详细信息。
有一个问题是 Delphi,其中 Internet 代码可以在 Win 10 上运行,但不能在 Win 7 上运行。我正在尝试将一个小项目连接到 haveibeenpwned.com (HIBP)。Win 7 返回“获取服务器证书时出错”。
为了尝试修复 Win 7 问题,我向 TNetHTTPRequest 和 TNetHTTPClient 添加了一个 OnValidateServerCertificate。在 Win 10 和 Win 7 中,似乎没有调用 OnValidateServerCertificate。
我已经在 2 台 Win 10 计算机和 2 台 Win 7 计算机上进行了测试,结果相同。1)为什么Win 7返回“获取服务器证书时出错?2) 为什么在 Win 10 或 Win 7 上没有调用 OnValidateServerCertificate?
谢谢你的帮助!
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.
Run Code Online (Sandbox Code Playgroud)
链接https://api.pwnedpasswords.com/range/55555(示例前 5 个字符哈希)在 IE 中返回证书错误。我在 Win 7 Internet Options, Advanced 中添加了 TLS 1.1 和 1.2。这允许浏览器工作。
程序还是不行。因此,我搜索了 Delphi 源(柏林)“获取服务器证书时出错”,导致“SNetHttpGetServerCertificate”。在 System.Net.HttpClient 中:
procedure THTTPClient.DoValidateServerCertificate(LRequest: THTTPRequest);
Run Code Online (Sandbox Code Playgroud)
...
LServerCertificate := DoGetSSLCertificateFromServer(LRequest);
if LServerCertificate.Expiry = 0 then
raise
ENetHTTPCertificateException.CreateRes(@SNetHttpGetServerCertificate);
Run Code Online (Sandbox Code Playgroud)
这似乎是唯一可以引发此异常的地方。不幸的是,从未在那里设置断点(即使打开了调试 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(柏林)和 Win 7 不兼容?
谢谢你的帮助!
小智 5
居然找到了解决方法,与Delphi无关。
来自 MS:
使用 WinHTTP 为使用 WINHTTP_OPTION_SECURE_PROTOCOLS 标志的安全套接字层 (SSL) 连接编写的应用程序和服务不能使用 TLS 1.1 或 TLS 1.2 协议。这是因为此标志的定义不包括这些应用程序和服务。
此更新添加了对 DefaultSecureProtocols 注册表项的支持,允许系统管理员指定在使用 WINHTTP_OPTION_SECURE_PROTOCOLS 标志时应使用哪些 SSL 协议。
这可以允许某些构建为使用 WinHTTP 默认标志的应用程序能够在本地利用较新的 TLS 1.2 或 TLS 1.1 协议,而无需对应用程序进行任何更新。
使固定:
https://support.microsoft.com/en-au/help/3140245/
| 归档时间: |
|
| 查看次数: |
5990 次 |
| 最近记录: |