簡體   English   中英

設置 SecurityProtocol 和 ServerCertificateValidationCallback 時“無法創建 SSL/TLS 安全通道”

[英]"Could not create SSL/TLS secure channel" while setting SecurityProtocol and ServerCertificateValidationCallback

我知道這個問題在 Stackoverflow 上被問過很多次,但是我看了很多答案,但我仍然找不到適合我的解決方案。

我有這段代碼,我在其中嘗試使用 WebClient 向服務器發送請求

using (var client = new CertificateWebClient())
{
    var postData = $"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:v3='http://xmldefs.volkswagenag.com/PP/QM/GroupProblemManagementService/V3'><soapenv:Header><To xmlns='http://www.w3.org/2005/08/addressing'>ws://volkswagenag.com/PP/QM/GroupProblemManagementService/V3</To><Action xmlns='http://www.w3.org/2005/08/addressing'>http://xmldefs.volkswagenag.com/PP/QM/GroupProblemManagementService/V3/KpmService/GetMultipleProblemDataRequest</Action><MessageID xmlns='http://www.w3.org/2005/08/addressing'>${{= \"urn:uuid:\" + UUID.randomUUID()}}</MessageID></soapenv:Header><soapenv:Body><v3:GetMultipleProblemData><UserAuthentification><UserId>{Username}</UserId></UserAuthentification><OverviewAddress><AddressTimestamp/><ContactPerson/><Description/><OrganisationalUnit>KPMEE-05</OrganisationalUnit><Group/><Plant>Z$</Plant></OverviewAddress><ActiveOverview>true</ActiveOverview><PassiveOverview>false</PassiveOverview></v3:GetMultipleProblemData></soapenv:Body></soapenv:Envelope>";
    var postArray = Encoding.UTF8.GetBytes(postData);
    try
    {
        var resposneData = Encoding.UTF8
                                .GetString(client.UploadData("https://ws-gateway-cert.volkswagenag.com/services", postArray));
        Debug.WriteLine(resposneData);
    }
    catch (WebException we)
    {
        var webResponse = (HttpWebResponse)we.Response;
        if (webResponse != null)
        {
            Debug.WriteLine(GetErrorText(webResponse.StatusCode.ToString()));
        }
        else
        {
            Debug.WriteLine(we);
        }
    }
}

現在由於服務器需要證書進行身份驗證,我創建了一個子 class 繼承自 WebClient 並使用 HttpWebRequest 添加證書。

internal class CertificateWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
        string filePath = "../../Resources/Systemuser PAG R_ PAG_KPM_PREH_MFL VWPKI A145CCD2D02592DB.p12";
        X509Certificate2 certificate = new X509Certificate2(filePath, ""); //password is not shown in here

        request.ClientCertificates.Add(certificate);
        return request;
    }
}

在調試模式下啟動程序時,出現以下錯誤:

請求已中止:無法創建 SSL/TLS 安全通道。

我嘗試通過將 SecurityProtocol 設置為 Tls1.2 來解決此問題,因為這是服務器正在使用的,將 Expect100Continue 設置為 true 並設置 ServerCertificateValidationCallback,正如許多響應中所建議的那樣。

internal class CertificateWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        ServicePointManager.Expect100Continue = true;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslError) => true;
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
        string filePath = "../../Resources/Systemuser PAG R_ PAG_KPM_PREH_MFL VWPKI A145CCD2D02592DB.p12";
        X509Certificate2 certificate = new X509Certificate2(filePath, ""); //password is not shown in here

        request.ClientCertificates.Add(certificate);
        return request;
    }
}

不幸的是,這也無法解決問題。 我知道證書是有效的,因為我通過 Soap UI 設置了一個測試環境,使用相同的證書、相同的用戶名和相同的 URI。 它工作得很好。 我使用 .NET 框架版本 4.8

我錯過了什么?

我能夠通過為 X509Certificate2 class 使用另一個構造函數來解決問題。我沒有使用X509Certificate2(string, string)我使用了X509Certificate(string, string, X509KeyStorageFlags)

internal class CertificateWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
        string filePath = "../../Resources/Systemuser PAG R_ PAG_KPM_PREH_MFL VWPKI A145CCD2D02592DB.p12";
        X509Certificate2 certificate = new X509Certificate2(filePath, "", X509KeyStorageFlags.UserKeySet); //password is not shown here

        request.ClientCertificates.Add(certificate);
        return request;
    }
}

通過這樣做,服務器接受了證書並且請求成功。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM