我认为我们发现了主要问题:Azure 存储,至少在与 Azure 云服务(但在可用的最新 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?
日志sn-p:
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 的回答最终在技术上给出了正确的解决方案,但它并没有给出 真正的原因,这是真正的问题(正如我所说在 cmets 中,我已经设置了这个,只是我 碰巧 设置了一个更高的值,改为 Tls12)。因此,虽然我总是宁愿不给出自己的答案而不是别人的答案,但我认为这对于其他在同样问题上苦苦挣扎的人来说更可取和更有帮助(事实上,当我看到他的答案时,它甚至没有向我注册为甚至与我所做的不同)。不过感谢 Jan 的帮助。