"无法创建SSL / TLS安全通道"自POODLE以来Azure Azure .NET API错误

时间:2014-10-15 22:19:52

标签: azure ssl azure-storage

读取工作,但创建/删除/更新时不要使用.NET Azure存储API库进行blob以及azure队列(也建立在存储上)。这是在ASP.NET MVC 5.2网站.NET 4.5.1中运行的,所有库都完全更新到最新版本。这个问题从昨天(10月14日)晚上突然出现,显然随着POODLE漏洞被人们所知。多年来一直使用这个API项目没有这个问题,并且部署的版本一直工作到那个时候。

令人沮丧的是,在我的开发/本地机器上,问题并没有出现。

错误显示之前有很长的延迟,可能是由于重试尝试或其他原因造成的。

请求已中止:无法创建SSL / TLS安全通道。

System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
   at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
   at System.Net.HttpWebRequest.GetRequestStream()
   at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext)   at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
   at System.Net.HttpWebRequest.GetRequestStream()
   at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext)

这是例外的全部。

2 个答案:

答案 0 :(得分:13)

我有完全相同的问题:昨天许多公司已经在服务器上解除了SSLv3,因此客户端在连接到安全端点时必须协商使用TLS。

在我的开发盒上运行时,一切都像以前一样。但是在我的所有生产服务器上,当连接到某些服务器时(不是全部 - 例如graph.facebook.com,mandrillapp.com和其他一些服务器显示该问题),我得到相同的异常。

有趣的是,重启应用程序解决了一小时的问题。然后错误再次出现。

经过一些谷歌搜索后,我找到了这条线

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

要有所帮助。问题是,这似乎是一个全局设置,并解决了一些但不是所有的连接问题。 Facebook API再次运行,但是例如,mandrill停止工作并在几个小时后再次显示异常。

问题似乎是,.NET HttpWebRequest类(以及WebClient类)或底层的https实现在协商通信协议方面存在问题。

我已经读过,TLS是.NET中的标准协议已经有几年了,而且SSLv3只是用作后备,但是,例外情况就是这样。

答案 1 :(得分:8)

我认为我们已经找到了主要问题:Azure存储,至少在与Azure Cloud Service进行通信时(在最新的Windows平台上可用),似乎

无法处理Tls 1.2安全协议。

所以设置:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // FAILS!

你必须设置:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; // or Tls11 ?

它也可能无法处理Tls 1.1。我可以检查一下,但是我厌倦了让这个项目再次工作,甚至一秒钟。

---更新--- Azure支持人员指出,在.NET 4.5(4.0及更早版本)之前,此枚举上唯一可用的Tls值只是.Tls(没有Tls11,Tls12)。

请参阅msdn docs

我认为Azure存储中的接收端然后(在他们自己的处理请求的内部堆栈上)没有使用.NET 4.5(有根据的猜测)。

---结束更新---

虽然在本地机器上没有问题。这让我想知道客户端(azure中托管的云服务虚拟机)本身是否缺少这个。

到目前为止,这似乎有效。

对于从远程访问实例获得的详细日志信息,这里有一些明显相关的日志,可能有助于某些人希望将来解决这个问题。在每种情况下,潜在的例外是:

System.Security.Authentication.AuthenticationException // (of type: `System.ComponentModel.Win32Exception)`

主要的错误消息是:

  

客户端和服务器无法通信,因为它们不具备   常用算法

显然,在这种情况下,其中一个(我认为云服务客户端?)无法处理Tls1.2?

记录片段:

    DetailID = 6
    Count:    4
    Type:     System.Security.Authentication.AuthenticationException
    Message:  A call to SSPI failed, see inner exception.
        Type:     System.ComponentModel.Win32Exception
        Message:  The client and server cannot communicate, because they do not possess a common algorithm
    Stack:    
        [HelperMethodFrame]
        System.Net.Security.SslState.ForceAuthentication(Boolean, Byte[], System.Net.AsyncProtocolRequest)
        [HelperMethodFrame]
        System.Net.Security.SslState.StartSendAuthResetSignal(System.Net.Security.ProtocolToken, System.Net.AsyncProtocolRequest, System.Exception)
        System.Net.Security.SslState.StartSendBlob(Byte[], Int32, System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.ProcessReceivedBlob(Byte[], Int32, System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.StartReceiveBlob(Byte[], System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.StartSendBlob(Byte[], Int32, System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.ForceAuthentication(Boolean, Byte[], System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.ProcessAuthentication(System.Net.LazyAsyncResult)
        System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
        System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
        System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
        System.Net.TlsStream.ProcessAuthentication(System.Net.LazyAsyncResult)
        System.Net.TlsStream.Write(Byte[], Int32, Int32)
        System.Net.ConnectStream.WriteHeaders(Boolean)
        System.Net.HttpWebRequest.EndSubmitRequest()
        System.Net.Connection.CompleteConnection(Boolean, System.Net.HttpWebRequest)
        System.Net.Connection.CompleteStartConnection(Boolean, System.Net.HttpWebRequest)
        System.Net.Connection.CompleteStartRequest(Boolean, System.Net.HttpWebRequest, System.Net.TriState)
        System.Net.Connection.SubmitRequest(System.Net.HttpWebRequest, Boolean)
        System.Net.ServicePoint.SubmitRequest(System.Net.HttpWebRequest, System.String)
        System.Net.HttpWebRequest.SubmitRequest(System.Net.ServicePoint)
        System.Net.HttpWebRequest.GetRequestStream(System.Net.TransportContext ByRef)
        System.Net.HttpWebRequest.GetRequestStream()
        Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[[System.__Canon, mscorlib]](Microsoft.WindowsAzure.Storage.Core.Executor.RESTCommand`1<System.__Canon>, Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy, Microsoft.WindowsAzure.Storage.OperationContext)
        Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStreamHelper(System.IO.Stream, System.Nullable`1<Int64>, Microsoft.WindowsAzure.Storage.AccessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)
        Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromByteArray(Byte[], Int32, Int32, Microsoft.WindowsAzure.Storage.AccessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)
        Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadText(System.String, System.Text.Encoding, Microsoft.WindowsAzure.Storage.AccessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)
        ... my own project's calls begin here ...

        DetailID = 7
    Count:    4
    Type:     System.Security.Authentication.AuthenticationException
    Message:  A call to SSPI failed, see inner exception.
        Type:     System.ComponentModel.Win32Exception
        Message:  The client and server cannot communicate, because they do not possess a common algorithm
    Stack:    
        [HelperMethodFrame]
        System.Net.TlsStream.ProcessAuthentication(System.Net.LazyAsyncResult)
        [HelperMethodFrame]
        System.Net.Security.SslState.ForceAuthentication(Boolean, Byte[], System.Net.AsyncProtocolRequest)
        [HelperMethodFrame]
        System.Net.Security.SslState.StartSendAuthResetSignal(System.Net.Security.ProtocolToken, System.Net.AsyncProtocolRequest, System.Exception)
        System.Net.Security.SslState.StartSendBlob(Byte[], Int32, System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.ProcessReceivedBlob(Byte[], Int32, System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.StartReceiveBlob(Byte[], System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.StartSendBlob(Byte[], Int32, System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.ForceAuthentication(Boolean, Byte[], System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.ProcessAuthentication(System.Net.LazyAsyncResult)
        System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
        System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
        System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
        System.Net.TlsStream.ProcessAuthentication(System.Net.LazyAsyncResult)
        System.Net.TlsStream.Write(Byte[], Int32, Int32)
        System.Net.ConnectStream.WriteHeaders(Boolean)
        System.Net.HttpWebRequest.EndSubmitRequest()
        System.Net.Connection.CompleteConnection(Boolean, System.Net.HttpWebRequest)
        System.Net.Connection.CompleteStartConnection(Boolean, System.Net.HttpWebRequest)
        System.Net.Connection.CompleteStartRequest(Boolean, System.Net.HttpWebRequest, System.Net.TriState)
        System.Net.Connection.SubmitRequest(System.Net.HttpWebRequest, Boolean)
        System.Net.ServicePoint.SubmitRequest(System.Net.HttpWebRequest, System.String)
        System.Net.HttpWebRequest.SubmitRequest(System.Net.ServicePoint)
        System.Net.HttpWebRequest.GetRequestStream(System.Net.TransportContext ByRef)
        System.Net.HttpWebRequest.GetRequestStream()
        Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[[System.__Canon, mscorlib]](Microsoft.WindowsAzure.Storage.Core.Executor.RESTCommand`1<System.__Canon>, Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy, Microsoft.WindowsAzure.Storage.OperationContext)
        Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStreamHelper(System.IO.Stream, System.Nullable`1<Int64>, Microsoft.WindowsAzure.Storage.AccessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)
        Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromByteArray(Byte[], Int32, Int32, Microsoft.WindowsAzure.Storage.AccessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)
        Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadText(System.String, System.Text.Encoding, Microsoft.WindowsAzure.Storage.AccessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)
        ... my own project's calls begin here ...

    DetailID = 8
    Count:    4
    Type:     System.Security.Authentication.AuthenticationException
    Message:  A call to SSPI failed, see inner exception.
        Type:     System.ComponentModel.Win32Exception
        Message:  The client and server cannot communicate, because they do not possess a common algorithm
    Stack:    
        [HelperMethodFrame]
        System.Net.TlsStream.ProcessAuthentication(System.Net.LazyAsyncResult)
        [HelperMethodFrame]
        System.Net.TlsStream.ProcessAuthentication(System.Net.LazyAsyncResult)
        [HelperMethodFrame]
        System.Net.Security.SslState.ForceAuthentication(Boolean, Byte[], System.Net.AsyncProtocolRequest)
        [HelperMethodFrame]
        System.Net.Security.SslState.StartSendAuthResetSignal(System.Net.Security.ProtocolToken, System.Net.AsyncProtocolRequest, System.Exception)
        System.Net.Security.SslState.StartSendBlob(Byte[], Int32, System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.ProcessReceivedBlob(Byte[], Int32, System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.StartReceiveBlob(Byte[], System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.StartSendBlob(Byte[], Int32, System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.ForceAuthentication(Boolean, Byte[], System.Net.AsyncProtocolRequest)
        System.Net.Security.SslState.ProcessAuthentication(System.Net.LazyAsyncResult)
        System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
        System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
        System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
        System.Net.TlsStream.ProcessAuthentication(System.Net.LazyAsyncResult)
        System.Net.TlsStream.Write(Byte[], Int32, Int32)
        System.Net.ConnectStream.WriteHeaders(Boolean)
        System.Net.HttpWebRequest.EndSubmitRequest()
        System.Net.Connection.CompleteConnection(Boolean, System.Net.HttpWebRequest)
        System.Net.Connection.CompleteStartConnection(Boolean, System.Net.HttpWebRequest)
        System.Net.Connection.CompleteStartRequest(Boolean, System.Net.HttpWebRequest, System.Net.TriState)
        System.Net.Connection.SubmitRequest(System.Net.HttpWebRequest, Boolean)
        System.Net.ServicePoint.SubmitRequest(System.Net.HttpWebRequest, System.String)
        System.Net.HttpWebRequest.SubmitRequest(System.Net.ServicePoint)
        System.Net.HttpWebRequest.GetRequestStream(System.Net.TransportContext ByRef)
        System.Net.HttpWebRequest.GetRequestStream()
        Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[[System.__Canon, mscorlib]](Microsoft.WindowsAzure.Storage.Core.Executor.RESTCommand`1<System.__Canon>, Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy, Microsoft.WindowsAzure.Storage.OperationContext)
        Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStreamHelper(System.IO.Stream, System.Nullable`1<Int64>, Microsoft.WindowsAzure.Storage.AccessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)
        Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromByteArray(Byte[], Int32, Int32, Microsoft.WindowsAzure.Storage.AccessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)
        Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadText(System.String, System.Text.Encoding, Microsoft.WindowsAzure.Storage.AccessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)
        ... my own project's calls begin here ...

Jan的答案在技术上最终提供了正确的解决方案,但它没有给出真正原因,这是真正的错误(正如我所说)在评论中,我已经设置了这个,只是我发生了来设置更高的值,而不是Tls12)。因此,虽然我总是不愿意给别人自己的答案,但我认为这对于那些在这个完全相同的问题上挣扎的人来说是更优选和有帮助的(事实上,当我看到他的回答时,它甚至没有注册给我甚至与我正在做的不同)。感谢Jan的帮助。