安全通道支持发生错误 - 经典ASP HTTP请求

时间:2014-01-25 19:10:36

标签: iis asp-classic xmlhttprequest windows-server-2012

我有一个在Windows Server 2012上运行的经典ASP网站。一个页面使用以下代码向https上的另一个应用程序发出HTTP请求:

Sub ShopXML4http(url, inStr, outStr, method, xmlerror)
  Dim objhttp
  Set objhttp = Server.CreateObject ("MSXML2.ServerXMLHTTP.6.0")
  objHttp.open method, url, false
  If Method="POST" Then
    objHttp.Send instr
  Else
    objHttp.Send
  End if   
  outstr=objHttp.responseText
  Set objhttp=nothing
End Sub

这段代码几乎在所有时间都可以正常工作(每天有数千个请求),但偶尔会出现这样的消息:

  

编号:-2147012739

     

描述:安全通道支持

发生错误      

来源:msxml6.dll

该应用程序最近已从旧的Windows 2003 Server迁移到2012 Server,这个问题在旧服务器上似乎永远不会出现问题。此外,虽然这个错误发生在网站上,我可以在VBScript中运行完全相同的代码,它工作正常。重置应用程序池似乎会使站点再次能够执行安全的HTTP请求(尽管它经常在我到达服务器之前自行修复)。

8 个答案:

答案 0 :(得分:17)

从2003年到2008 R2迁移后,我遇到了完全相同的问题并找到了解决方案。变化:

Set objhttp = Server.CreateObject ("MSXML2.ServerXMLHTTP.6.0")

为:

Set objhttp = Server.CreateObject ("MSXML2.XMLHTTP.6.0")

你的问题就会消失。

我试图找到两个对象的优缺点,但还没有找到不使用XMLHTTP的理由。

答案 1 :(得分:7)

我遇到了同样的问题并尝试过各种各样的帖子提供的解决方案但最终没有成功,直到现在。我将详细介绍解决问题的解决方案,因为我的情况是PayPal。我没有开一个新帖子,因为这可能不仅仅是未来的PayPal问题。

该解决方案是针对类似问题的多个stackoverflow发布解决方案的组合,但这似乎是最好的解决方案。

问题

尝试使用PayPal Sandbox使用经典ASP在Windows Server 2008上测试PayPal IPN会返回错误“安全通道支持中出错”。

为什么这是一个问题

PayPal要求与其系统的所有通信尽可能安全。您将需要一个TLS 1.2连接。默认情况下,Windows Server 2008不是TLS 1.2。

PayPal表示您需要一个Verisign G5证书,而不是您运行代码的域,而是需要Verisign G5证书。我也没有安装任何PayPal证书,因为我不使用API​​。我不相信您需要来自HTTPS站点的通信 - 虽然我的域使用标准的GoDaddy EV证书进行保护,尽管我之后在非HTTPS站点上进行了测试,但也有效。

我的解决方案

  1. 首先通过SSL Labs检查您的服务器正在使用哪种安全性。 应该是TLS1.2或更高版本,而不是其他TLS或SSL。它还必须具有SHA256加密。 您可能需要修补服务器:https://support.microsoft.com/en-us/kb/3106991

  2. 使用IISCrypto设置正确的TLS和密码。我使用了stackoverflow上其他地方提供的注册表更改,但这不起作用,实际上完全搞砸了我的服务器使用HTTPS帖子,而不仅仅是我的开发网站! IISCrypto也处理密码。

  3. 确保您的应用程序池是v4.5 ,这本身并不清楚,因为IIS可能只提供v4.0作为选项。然而,这可能实际上是v4.5。您可以通过https://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx验证这一点。

  4. 在您的代码中,您需要使用Server.CreateObject ("MSXML2.XMLHTTP.6.0"),而不是上面提到的Server.CreateObject ("MSXML2.ServerXMLHTTP.6.0")

  5. 现在我不知道为什么非服务器XMLHTTP的工作原理与它背后的文档相反。现在,经过10天的压力,恐慌和沮丧我不在乎!我希望这对其他人有用。

    找到解决方案是一场噩梦,所以我会在下面添加一些短语来帮助其他人搜索:

      

    PayPal IPN因服务器错误而失败

         

    PayPal SSL Windows 2008错误

         

    安全通道支持

    发生错误      

    经典ASP PayPal Sandbox SSL错误

    我想公开感谢Rackspace和GoDaddy对此的帮助。我想公开声明我发现PayPal有史以来最糟糕的技术支持,只是不关心,不断指向他们自己的文档,如果他们回应。他们说他们自2014年9月以来一直在发送有关此事的电子邮件,但我从未收到过。这些新要求在PayPal Sandbox上很活跃,但在2016年9月上线。我只是在开发一个新的解决方案,因此需要沙箱 - 如果你正在运行,你将无法知道问题,直到它击中然后你死在水里。尽快在PayPal沙箱上测试您的整个支付系统!!

答案 2 :(得分:3)

以上答案均不适用于我的情况。然后我跳到这里的链接:

https://support.microsoft.com/en-za/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-a-default-secure-protocols-in

此更新提供对Windows Server 2012,Windows 7 Service Pack 1(SP1)和Windows Server 2008 R2 SP1中的传输层安全性(TLS)1.1和TLS 1.2的支持。

使用WinHTTP进行的使用WINHTTP_OPTION_SECURE_PROTOCOLS标志的安全套接字层(SSL)连接编写的应用程序和服务不能使用TLS 1.1或TLS 1.2协议。这是因为此标志的定义不包括这些应用程序和服务。

此更新增加了对DefaultSecureProtocols注册表项的支持,该注册表项使系统管理员可以指定使用WINHTTP_OPTION_SECURE_PROTOCOLS标志时应使用哪些SSL协议。

这可以使某些使用WinHTTP默认标志构建的应用程序能够在不更新应用程序的情况下,原生地利用更新的TLS 1.2或TLS 1.1协议。

当某些Microsoft Office应用程序从SharePoint库或Web文件夹,用于DirectAccess连接的IP-HTTPS隧道以及其他应用程序(例如通过使用WebClient通过WebDav,WinRM等技术)打开文档时,情况就是这样以及其他。

此更新不会更改手动设置安全协议而不通过默认标志的应用程序的行为。

Client service服务器上通过TLS出站到服务器的

Windows 2008 R2响应了该错误。我以为可能是密码套件兼容性。 Wireshark请求中的Client Hello跟踪指示版本为TLS 1.0,但服务器要求TLS 1.2。从客户端服务发送到出站服务器的密码套件很好。问题是Windows服务器上的客户端服务或应用程序默认使用系统默认值,而不是TLS 1.2。

解决方案是添加一个名为DefaultSecureProtocols的注册表子项,其值对应于应支持的TLS版本。将类型为DWORD的注册表子项添加到以下位置:

  • HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Internet设置\ WinHttp
  • HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Internet设置\ WinHttp

对于Internet Explorer修复,可以将名称为SecureProtocols的相似注册表子项(类型也为DWORD)添加到以下位置:

  • HKEY_CURRENT_USER \ Software \ Microsoft \ Windows \ CurrentVersion \ Internet设置
  • HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Internet设置

下面您可以找到两个子项的值表:

DefaultSecureProtocols Value         Protocol enabled
0x00000008                           Enable SSL 2.0 by default
0x00000020                           Enable SSL 3.0 by default
0x00000080                           Enable TLS 1.0 by default
0x00000200                           Enable TLS 1.1 by default
0x00000800                           Enable TLS 1.2 by default

例如:

管理员希望覆盖WINHTTP_OPTION_SECURE_PROTOCOLS的默认值,以指定TLS 1.1和TLS 1.2。

取TLS 1.1的值(0x00000200)和TLS 1.2的值(0x00000800),然后将它们加到计算器中(在程序员模式下),得到的注册表值为0x00000A00。

我将 0x00000A00 用作两个子项的值,并成功解决了该问题。

如果您不想手动输入注册表子项和值,也可以从Microsoft获得简易修复(链接在此处:https://aka.ms/easyfix51044)。

答案 3 :(得分:2)

错误代码疑难解答:

  1. -2147012739是一个HRESULT。
  2. 以十六进制表示,即0x80072F7D。
  3. 看看LOWORD:0x2F7D。
  4. 将其转换回十进制:12157。
  5. 查找12157错误代码。
  6. 发现它匹配:ERROR_WINHTTP_SECURE_CHANNEL_ERROR
  7. 一些Google-fu发现http://msdn.microsoft.com/en-us/library/windows/desktop/aa383770(v=vs.85).aspx指出:

    ERROR_WINHTTP_SECURE_CHANNEL_ERROR

    12157

    表示发生了与安全通道有关的错误(相当于以“winerror.h”头文件中列出的“SEC_E_”和“SEC_I_”开头的错误代码)。

    但是,您已经发现了这一点,因为您收到的消息是“说明:安全通道支持中发生错误”。所以这导致我们回到我们开始的地方。

    我做的另一个观察是你的代码是一个非异步的WinHTTP请求(我知道它必须在ASP中运行),但是,由于频率很高,你的机器可能会处理更多并发一个WinHTTP请求。我已经看到一些Windows通过阻止延迟的请求故意限制活动并发WinHTTP请求的总数。例如,在Windows 7计算机上,进程不能向同一远程服务器发出超过2个并发请求。即第3,第4 ......请求将被阻止,直到前两个完成。

    一种解决方案是在多个应用程序池或更多服务器上对传入请求进行负载均衡。

答案 4 :(得分:2)

这一切都有效但是在Windows 7上使用IIS7.5和经典asp的TLS1.2支持的“关键”缺失位在注册表中设置了这个: -

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp]
"DefaultSecureProtocols"=dword:00000800

我希望能为您节省一天的烦恼,重新启动和抓挠! :)

此代码段对测试非常有用。 https://www.howsmyssl.com/

<%
Set winhttp = Server.CreateObject("WinHTTP.WinHTTPRequest.5.1")
winhttp.open "GET", "https://howsmyssl.com/a/check", False
winhttp.Send
Response.Write winhttp.responseText 
%>

答案 5 :(得分:2)

我们对这个问题有所不同,我们花了一些时间才弄明白 以下是这种情况:一个较旧的Linux服务器,托管一个用PHP编写的应用程序,并通过webservice调用提供数据。服务器正在使用HTTPS。使用winHTTP 5.2库,使用代码调用来自不同客户端的调用。 (Winhttp.dll)

症状:使用“POST”命令进行重复的winHTTP调用时,我们的客户端现在收到零星的错误消息。消息是“提供给函数的缓冲区很小。”或“安全通道支持中发生错误”。经过大量搜索后,我们发现客户端的服务器在事件查看器中记录了与可见错误消息相对应的“Schannel事件ID 36887警报代码20”。

解决方案:我们发现旧的Linux服务器无法支持TLS 1.2。 (CentOS 5.11)我们还了解到,我们的一些客户最近(2016年夏天)对其Microsoft服务器应用了更新。 (Server 2008,server 2012)修复是强制他们的服务器使用TLS 1.1进行webservice调用。对我来说很奇怪的部分是Internet Explorer中用于更改TLS的设置对问题没有影响。但是,通过更改组策略中的设置,我们能够解决问题。我们关于此事的技术顾问指出,这种变化确实很模糊,但第三方供应商提供了快速解决方案。该工具称为Nartac的IIS Crypto。 https://www.nartac.com/Products/IISCrypto/Download  该工具允许您专门选择协议。    我们现在正在使用新服务器来托管我们的应用程序(CentOS 6),然后应该能够使用TLS 1.2协议!

答案 6 :(得分:1)

在Windows Server 2016 Classic ASP脚本中,从Windows Server 2012 R2中获取HTTPS URL,我最近不得不从SecureProtocols中删除SSL 2.0,以阻止此安全通道错误-2147012739。

' Use the latest client
Set httpClient = Server.CreateObject("WinHttp.WinHttpRequest.5.1")

' allow only TLS 1.2 or TLS 1.1
Const WHR_SecureProtocols = 9
httpClient.Option(WHR_SecureProtocols) = &h0800 + &h0200 
' Other values: TLS 1.0 &h0080, SSL 3.0 &h0020, SSL 2.0 &h0008 
' NB Including SSL 2.0 stops https to Windows Server 2012 R2 working

' Other options you may want to set, from https://docs.microsoft.com/en-us/windows/desktop/winhttp/winhttprequestoption 

' Ignore certificate errors
Const WHR_SslErrorIgnoreFlags = 4
httpClient.Option(WHR_SslErrorIgnoreFlags) = &h3300 

' Don't bother checking cert, or risking failure if we can't check
Const WHR_EnableCertificateRevocationCheck = 18
httpClient.Option(WHR_EnableCertificateRevocationCheck) = False 

答案 7 :(得分:0)

几个月前我自己遇到了这个错误。大多数情况下,此问题是由无效的SSL证书引起的。考虑到在您刚刚迁移到新服务器的帖子时,您可能只需要重新安装SSL证书。

我意识到这个问题很老,但希望其他人可以从我的答案中受益。