简体   繁体   English

仅在azure上:无法创建SSL / TLS安全通道

[英]Only on azure: Could not create SSL/TLS secure channel

I run an application on the Azure application Standard: 1 Small plan. 我在Azure应用程序标准:1小计划上运行应用程序。 Framework is 4.6.1 框架是4.6.1

This application is calling a SSL secured API. 此应用程序正在调用SSL安全API。 The SSL is published by StartCom Class 1 DV Server CA, my local browser tells me that the certificate is valid. SSL由StartCom Class 1 DV Server CA发布,我的本地浏览器告诉我证书有效。

If I run the application on my local machine everything works. 如果我在本地计算机上运行该应用程序一切正常。 However, when deployed to azure it fails with follwing error: 但是,当部署到azure时,它会失败并出现以下错误:

System.Net.Http.HttpRequestException: An error occurred while sending the request. System.Net.Http.HttpRequestException:发送请求时发生错误。 ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel. ---> System.Net.WebException:请求已中止:无法创建SSL / TLS安全通道。

at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) 在System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)

at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar) 在System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)

--- End of inner exception stack trace --- ---内部异常堆栈跟踪结束---

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)

at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)

The code: 代码:

public async Task<List<QutationOverview>> GetAll(string url, DateTime lastActionDate)
    {
        var result = string.Empty;

        try
        {


            var userName = await _settingManager.GetSettingValueAsync("API.UserName");
            var password = await _settingManager.GetSettingValueAsync("API.Password");


            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls |
                                                   SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;


            ServicePointManager
                .ServerCertificateValidationCallback +=
                (sender, cert, chain, sslPolicyErrors) => true;


            //Add date filter
            //Always request qutations where the last action took place >= Yesterday
            var requestUrl =
                $"GetALL/?last_action_date={lastActionDate.AddDays(-1).ToString("yyyy-MM-dd")}&format=json";


            var baseAddress = new Uri(url);
            var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{userName}:{password}"));

            Logger.InfoFormat("GetAllQuotationsAsync for url {0}{1}", url, requestUrl);

            using (var httpClient = new HttpClient {BaseAddress = baseAddress})
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
                using (var response = await httpClient.GetAsync(requestUrl))
                {
                    result = await response.Content.ReadAsStringAsync();
                    Logger.Info(result);
                }
            }
        }

        catch (Exception ex)
        {
            Logger.ErrorFormat("GetAllQuotationsAsync {0}: {1}", url, ex);
        }
        var data = JsonConvert.DeserializeObject<List<QutationOverview>>(result);

        return data;
    }

As you can see I skip the validation of the certificate and added the security protocols. 如您所见,我跳过了证书的验证并添加了安全协议。

However, the request is still failing. 但是,请求仍然失败。


Here is the caputred response http://textuploader.com/5ers0 这是受限制的响应http://textuploader.com/5ers0


Do you have any idea how to get this one working on Azure? 你知道如何让这个在Azure上运行吗?

Capture the TLS handshake. 捕获TLS握手。 If your ServerHello is missing you most probably don't have a common cipher suite with the remote. 如果您的ServerHello丢失,您很可能没有带遥控器的通用密码套件。

Run both through https://www.ssllabs.com/ssltest/ to check supported cipher suites at both ends. 通过https://www.ssllabs.com/ssltest/运行以检查两端支持的密码套件。 For Windows Server, cipher suites can only be enabled or disabled globally (as in no distinction between client/server component) so that's why this makes for a good test. 对于Windows Server,只能全局启用或禁用密码套件(因为客户端/服务器组件之间没有区别),这就是为什么这样可以进行良好的测试。

UPDATE: Found a glaring problem in my reasoning, App Service has a frontend layer and that's where TLS terminates, so comparing ciphers that way goes nowhere. 更新:在我的推理中发现了一个明显的问题,App Service有一个前端层,这就是TLS终止的地方,所以比较这种方式的密码无处可去。

Instead, run 相反,跑

Get-TlsCipherSuite

from Kudu's PowerShell and compare ciphers against your remote API's (the ciphers of which you can check over at https://ssllabs.com/ssltest ). 来自Kudu的PowerShell并将密码与您的远程API(您可以在https://ssllabs.com/ssltest上查看的密码)进行比较。 You should have at least one match. 你应该至少有一场比赛。

If none match, you'll need to switch to Cloud Services or VMs and enable at least one of the cipher suites your remote speaks. 如果不匹配,则需要切换到云服务或虚拟机,并启用至少一个远程说话的密码套件。 Having to go this direction usually means one thing -- your remote is using weak cryptography (SSL 3.0 or TLS 1.0 with RC4) and you should have a chat with those citizens, or find new citizens that are rocking TLS 1.2. 必须走这个方向通常意味着一件事 - 你的遥控器正在使用弱密码术(SSL 3.0或TLS 1.0与RC4),你应该与这些公民聊天,或找到摇摆TLS 1.2的新公民。

From your System.Net trace: 从您的System.Net跟踪:

[8356] 00000000 : 15 03 03 00 02

That's byte sequence for Fatal Handshake Error , which builds on my no common cipher theory. 这是致命握手错误的字节序列,它建立在我的通用密码理论之上。

Note the first byte ( 0x15 ): 注意第一个字节( 0x15 ):

 Record Type Values       dec      hex
 -------------------------------------
 CHANGE_CIPHER_SPEC        20     0x14
 ALERT                     21     0x15
 HANDSHAKE                 22     0x16
 APPLICATION_DATA          23     0x17

I ran across this error when hosting a client's certificate on Azure's App Services. 在Azure的App Services上托管客户端证书时,我遇到了这个错误。 The fix was to set WEBSITE_LOAD_CERTIFICATES in the App Settings. 修复是在应用程序设置中设置WEBSITE_LOAD_CERTIFICATES。

You can set it as " * " to allow all certificates, or you can define specific certificate thumbprints to allow. 您可以将其设置为“*”以允许所有证书,或者您可以定义允许的特定证书指纹。 See more info here. 在这里查看更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM