使用 Azure Functions 中的 SSL3 调用外部 API

Using SSL3 from Azure Functions to Call External API

我们有一个 .NET 应用程序需要与 API 交互,严格要求 SSL3 才能使 API 工作,但是我们不希望我们的整个站点在该安全协议下运行.

为了在 .NET Framework 中实现这一点,我们使用了 AppDomain and, therefore, remoting。但是,我们正在将我们的应用程序移植到 .NET Core 2.0,我们不再可以使用该功能。

我们建议的解决方案是使用 Azure Functions 来实现无服务器功能,该功能可以联系 API 和 return 交互结果,因此充当代理。

这是我们在函数中设置的一些代码:

// set the protocol to SSL3 app wide
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
// ignore any SSL errors
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

但是 运行 它给我们以下错误:

System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.ComponentModel.Win32Exception: The client and server cannot communicate, because they do not possess a common algorithm
   at System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface SecModule, String package, CredentialUse intent, SecureCredential scc)
   at System.Net.Security.SecureChannel.AcquireCredentialsHandle(CredentialUse credUsage, SecureCredential& secureCredential)
   at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPrint)
   at System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32 offset, Int32 count, Byte[]& output)
   at System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32 offset, Int32 count)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.TlsStream.CallProcessAuthentication(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
   at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.ConnectStream.WriteHeaders(Boolean async)
   --- End of inner exception stack trace ---
   at System.Net.HttpWebRequest.GetResponse()
   at Submission#0.<Run>d__1.MoveNext() in :line 15

是否可以让 Azure Functions 执行我们正在尝试做的事情,或者我们正在尝试设置的设置是否在沙盒环境中不受尊重?

Azure Functions 在 Windows 工作人员之上运行,就像 Web 应用程序一样,因为它们都是应用程序服务的一部分。下面是同一个沙箱。

如果你在 Kudu 中使用 PowerShell your way around the registry,你会发现 SSL 3.0 在系统范围内被禁用,这对于 any 现代服务是预期的。

摘自 Ivan Ristić 的优秀 Bulletproof SSL 和 TLS 一书:

DisabledByDefault — This setting is for applications that do not explicitly configure enabled protocols but use system defaults. If the entry is not present or if the value is 0, the protocol is enabled by default. If the value is 1, the protocol is disabled by default. Normally, Windows will disable SSL 2 and leave all other protocols enabled.

运行 SSL 3.0-only API 的人在过去 10 年里休假太多了。对那些人讲一些道理。 SSL 3.0 容易受到 BEAST 攻击,Microsoft 的实现中没有 AES,不支持 GCM、SHA256 和 SHA384 套件,也没有椭圆曲线密码术,因此没有前向保密。

如果依赖 SSL 3.0 晚上睡觉没有问题,则必须使用 .NET/Windows 提供的 different TLS library(System.Security 和 SCHANNEL ). OpenSSL、BoringSSL、GnuTLS、LibreSSL 如果您找到 C# 包装器或者您有足够的时间自己动手,它们都是选项。

这里真正的解决方案是通过虚拟机代理所有请求。你控制 OS,你控制 TLS 堆栈。然后您可以对您的遥控器使用 SSL 3.0。我不敢相信我会这么说 - 给我他们的 phone 号码!

更新:您现在可以使用(更多)轻量级容器实例来代理 SSL 3.0 流量。参见 https://docs.microsoft.com/en-us/azure/container-instances/container-instances-overview