我们使用 WinInet 和 Delphi 通过 HTTPS 进行通信。 WinInet 中是否有一个函数可以返回 session 中协商的协议(protocol),即 TLS1.1、TLS 1.2 等。
最佳答案
不幸的是,显然不是(在 Windows 7 上使用 Internet Explorer 11 进行测试)。
使用 InternetQueryOption
与 INTERNET_OPTION_SECURITY_CERTIFICATE
或INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT
是我在 WinInet 文档中可以找到的最接近的(请参阅 lpszProtocolName
中的 INTERNET_CERTIFICATE_INFO
),但它们返回空字符串(请参阅下面的输出)。
lpszProtocolName Pointer to a buffer that contains the name of the protocol used to provide the secure connection. The application must call LocalFree to release the resources allocated for this parameter.
我找不到任何其他内容表明 Wininet 公开了底层 SChannel 连接属性。
program test_wininet;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Winapi.Windows,
Winapi.Wininet;
type
// fixed declaration
PInternetCertificateInfo = ^TInternetCertificateInfo;
TInternetCertificateInfo = record
ftExpiry: TFileTime;
ftStart: TFileTime;
lpszSubjectInfo: PAnsiChar;
lpszIssuerInfo: PAnsiChar;
lpszProtocolName: PAnsiChar;
lpszSignatureAlgName: PAnsiChar;
lpszEncryptionAlgName: PAnsiChar;
dwKeySize: DWORD;
end;
procedure FreeCertificateInfo(var Info: TInternetCertificateInfo);
begin
if Assigned(Info.lpszSubjectInfo) then
LocalFree(NativeUInt(Info.lpszSubjectInfo));
if Assigned(Info.lpszIssuerInfo) then
LocalFree(NativeUInt(Info.lpszIssuerInfo));
if Assigned(Info.lpszProtocolName) then
LocalFree(NativeUInt(Info.lpszProtocolName));
if Assigned(Info.lpszSignatureAlgName) then
LocalFree(NativeUInt(Info.lpszSignatureAlgName));
if Assigned(Info.lpszEncryptionAlgName) then
LocalFree(NativeUInt(Info.lpszEncryptionAlgName));
end;
function GetCertificateInfo(H: HINTERNET): TInternetCertificateInfo;
var
Size: Cardinal;
begin
Size := SizeOf(Result);
FillChar(Result, Size, 0);
Win32Check(InternetQueryOption(H, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, @Result, Size));
end;
function GetCertificateInfoStr(H: HINTERNET): AnsiString;
var
Buffer: array[0..1024] of AnsiChar;
BufferSize: Cardinal;
L: Integer;
begin
Result := '';
BufferSize := SizeOf(Buffer);
FillChar(Buffer, BufferSize, 0);
Win32Check(InternetQueryOption(H, INTERNET_OPTION_SECURITY_CERTIFICATE, @Buffer[0], BufferSize));
L := StrLen(PAnsiChar(@Buffer[0]));
if L > 0 then
SetString(Result, Buffer, L);
end;
procedure Main;
var
H, H2: HINTERNET;
Info: TInternetCertificateInfo;
SysTime: TSystemTime;
begin
H := InternetOpen('test', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
try
H2 := InternetOpenUrl(H, 'https://www.microsoft.com', nil, 0, INTERNET_FLAG_NO_UI or INTERNET_FLAG_SECURE, 0);
try
Writeln('InternetQueryOption with INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT: ');
Info := GetCertificateInfo(H2);
try
Writeln('Subject:');
Writeln(Info.lpszSubjectInfo);
Writeln('Issuer:');
Writeln(Info.lpszIssuerInfo);
Writeln(Format('Security Protocol: %s', [Info.lpszProtocolName]));
Writeln(Format('Signature Type: %s', [Info.lpszSignatureAlgName]));
Writeln(Format('Encryption Type: %s', [Info.lpszEncryptionAlgName]));
FileTimeToSystemTime(Info.ftStart, SysTime);
Writeln(Format('Effective Date: %s', [FormatDateTime('dd/mmm/yy hh:nn:ss', SystemTimeToDateTime(SysTime))]));
FileTimeToSystemTime(Info.ftExpiry, SysTime);
Writeln(Format('Expiration Date: %s', [FormatDateTime('dd/mmm/yy hh:nn:ss', SystemTimeToDateTime(SysTime))]));
Writeln(Format('Key size: %d', [Info.dwKeySize]));
Writeln;
finally
FreeCertificateInfo(Info);
end;
Writeln('InternetQueryOption with INTERNET_OPTION_SECURITY_CERTIFICATE:');
Writeln(GetCertificateInfoStr(H2));
Writeln;
finally
InternetCloseHandle(H2);
end;
finally
InternetCloseHandle(H);
end;
end;
begin
try
Main;
Readln;
except
on E: Exception do
begin
ExitCode := 1;
Writeln(Format('[%s] %s', [E.ClassName, E.Message]));
end;
end;
end.
上面的代码产生以下输出:
InternetQueryOption with INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT:
Subject:
US
Washington
Private Organization
600413485
US
98052
Washington
Redmond
1 Microsoft Way
Microsoft Corporation
www.microsoft.com
Issuer:
US
Symantec Corporation
Symantec Trust Network
Symantec Class 3 EV SSL CA - G3
Security Protocol:
Signature Type:
Encryption Type:
Effective Date: 24-Mar-16 00:00:00
Expiration Date: 25-Mar-18 23:59:59
Key size: 256
InternetQueryOption with INTERNET_OPTION_SECURITY_CERTIFICATE:
Subject:
US
Washington
Private Organization
600413485
US
98052
Washington
Redmond
1 Microsoft Way
Microsoft Corporation
www.microsoft.com
Issuer:
US
Symantec Corporation
Symantec Trust Network
Symantec Class 3 EV SSL CA - G3
Effective Date: 24-Mar-16 00:00:00
Expiration Date: 25-Mar-18 23:59:59
Security Protocol: (null)
Signature Type: (null)
Encryption Type: (null)
Privacy Strength: High (256 bits)
关于delphi - WinInet 能否返回正在使用的 TLS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37275395/