gpt4 book ai didi

delphi - Wininet SSL 客户端验证异常

转载 作者:太空宇宙 更新时间:2023-11-03 13:18:50 26 4
gpt4 key购买 nike

我有一个用于 HTTPs 切换到 Wininet 的爬虫。

这通常效果很好,但对于网站我会出错ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED

示例代码:

vErrorNone := HttpSendRequest(HttpOpen_Request, nil, 0, nil, 0);
if vErrorNone = False then
begin
vErrorID := GetLastError;
if (vErrorID = ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED) then
begin
// this error
end
;
end
;

然后我尝试了一个实验:

      TmpFakePointer := nil;
vErrorNone :=
InternetErrorDlg(
GetDesktopWindow()
,
HttpOpen_Request
,
ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED
,
0
or FLAGS_ERROR_UI_FILTER_FOR_ERRORS
or FLAGS_ERROR_UI_FLAGS_GENERATE_DATA
or FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS
,
TmpFakePointer
)
= ERROR_SUCCESS
;
if vErrorNone then
begin
vErrorNone := HttpSendRequest(HttpOpen_Request, nil, 0, nil, 0);
end
;

但是,这里有两点很奇怪:

  • 1) 没有对话框显示
  • 2) 有效
  • 2.1) 第二个 HttpSendRequest 没有错误
  • 2.2) 返回有效数据

它发现上面的组合非常奇怪并且与文档相反。由于用户没有选择任何证书,为什么会这样呢?如果当无法显示对话框时 Wininet 回退到匿名客户端身份验证证书(我假设我给了它不正确的句柄来显示对话框?尽管如果我明确给它一个错误的句柄它会出错)有没有办法直接选择它没有调用 InternetErrorDlg?

最佳答案

您可以做两件事:

1:将证书错误显示给用户,让他决定是否继续。
2:忽略您收到的任何证书错误。

我将向您展示如何执行第二个选项:

当您收到 ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED 或任何其他证书错误时,您需要调用 InternetSetOptions 来告诉 wininet 它应该忽略该错误并继续。之后,您必须重新发送请求。

function SetToIgnoreCerticateErrors(var aErrorMsg: string): Boolean;
var
vDWFlags: DWord;
vDWFlagsLen: DWord;
begin
Result := False;
try
vDWFlagsLen := SizeOf(vDWFlags);
if not InternetQueryOptionA(oRequestHandle, INTERNET_OPTION_SECURITY_FLAGS, @vDWFlags, vDWFlagsLen) then begin
aErrorMsg := 'Internal error in SetToIgnoreCerticateErrors when trying to get wininet flags.' + GetWininetError;
Exit;
end;
vDWFlags := vDWFlags or SECURITY_FLAG_IGNORE_UNKNOWN_CA or SECURITY_FLAG_IGNORE_CERT_DATE_INVALID or SECURITY_FLAG_IGNORE_CERT_CN_INVALID or SECURITY_FLAG_IGNORE_REVOCATION;
if not InternetSetOptionA(oRequestHandle, INTERNET_OPTION_SECURITY_FLAGS, @vDWFlags, vDWFlagsLen) then begin
aErrorMsg := 'Internal error in SetToIgnoreCerticateErrors when trying to set wininet INTERNET_OPTION_SECURITY_FLAGS flag .' + GetWininetError;
Exit;
end;
Result := True;
except
on E: Exception do begin
aErrorMsg := 'Unknown error in SetToIgnoreCerticateErrors.' + E.Message;
end;
end;
end;


vErrorNone := HttpSendRequest(HttpOpen_Request, nil, 0, nil, 0);
if vErrorNone = False then
begin
vErrorID := GetLastError;
if (vErrorID = ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED) then
begin
//call SetToIgnoreCerticateErrors
//re-send the request
end
end
end;

我已经从我的 wininet API 中提取了 SetToIgnoreCerticateErrors,它可能无法准确编译。

这些是步骤:

1 - 获取错误
2 - 检查错误是否为证书错误
3 - 如果是证书错误,他们会像我一样调用 InternetSetOption。
4 - 重新发送请求。

我不知道如何实现第一个选项“向用户显示证书错误并让他决定是否继续。”因为我从来不需要这样做。

另外,检查一下:How To Handle Invalid Certificate Authority Error with WinInet

希望对你有帮助。

关于delphi - Wininet SSL 客户端验证异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9861309/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com