C#使用libcurl查找已协商的TLS版本
在我的C#代码中,我使用libcurl.dll,并用 CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45 来判断正在协商的TLS版本,我不确定这个常量是否正确。
下面的代码正确吗?因为 cipherName 的结果总是 \u0001,不管网站使用的是TLS 1.2还是1.3?
private readonly curl_easy_getinfo_ptr _getInfoPtr;
_getInfoPtr = GetFunction<curl_easy_getinfo_ptr>("curl_easy_getinfo");
if (_getInfoPtr(curl, 0x400000 + 45, out IntPtr cipherPtr) == 0 && cipherPtr != IntPtr.Zero)
{
string cipherName = Marshal.PtrToStringAnsi(cipherPtr) ?? "";
}
解决方案
SSL_get_version() 会返回一个类似 "TLSv1.2" 或 "TLSv1.3" 的字符串。需要注意的一点——信息指针只有在连接打开时才有效,因此你需要在写回调中读取它,而不是在curl_easy_perform返回之后再读取。
@EchoOverflow 谢谢,我现在已经得到结果,之前我是在 int res = _perform(curl); 之后调用 SSL_get_version,但它应该放在 writeCallback,下面是可行的解决方案
// --- CALLBACK BODY (Dukungan > 100MB) ---
nuint writeDelegate(nint ptr, nuint size, nuint nmemb, nint userp)
{
// Get TLS Version
if (_getInfoPtr(curl, 0x400000 + 45, out IntPtr cipherPtr) == 0 && cipherPtr != IntPtr.Zero)
{
var info = Marshal.PtrToStructure<Curl_tlssessioninfo>(cipherPtr);
if (info.backend == 1 && info.internals != IntPtr.Zero)
{
IntPtr versionStringPtr = _getSslVersion(info.internals);
response.TlsVersion = Marshal.PtrToStringAnsi(versionStringPtr) ?? "Unknown";
}
}
int length = (int)size * (int)nmemb;
byte[] buffer = new byte[length];
Marshal.Copy(ptr, buffer, 0, length);
ms.Write(buffer, 0, length); // Menulis ke Stream lebih stabil untuk data besar
return (UIntPtr)length;
}
_setOpt(curl, 20011, Marshal.GetFunctionPointerForDelegate((WriteCallback)writeDelegate));
// --- Execution ---
int res = _perform(curl);
if (res == 0) // CURLE_OK
{
// previously it called here
// if (_getInfoPtr(curl, 0x400000 + 45, out IntPtr cipherPtr) == 0 && cipherPtr != IntPtr.Zero)...
// 1. Get Status Code
_getInfo(curl, 0x200000 + 2, out long statusCode);
response.StatusCode = (int)statusCode;
response.Body = ms.ToArray();
}
return response;
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。