我认为我们已经找到了主要问题:Azure Storage,在使用 Azure 云服务(在最新的 Windows 平台上)与其通信时,似乎无法处理 Tls 1.2 安全协议。
因此设置:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
您需要设置:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
它可能也无法处理Tls 1.1。我可以检查一下,但我很担心这个项目再次出现问题,哪怕只有一秒钟。
--- 更新 ---
Azure支持人员指出,在.NET 4.5之前(4.0及更早版本),此枚举中唯一可用的Tls值是.Tls(没有Tls11、Tls12)。
请参见msdn文档。
我敢打赌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的帮助。
SecurityProtocol
被设置的其他位置,果然被重置为Ssl
。 谢谢! - CodeNaked