ColdFusion CFHTTP I/O 异常:peer not authenticated - 即使在将证书添加到 Keystore 之后

Posted

技术标签:

【中文标题】ColdFusion CFHTTP I/O 异常:peer not authenticated - 即使在将证书添加到 Keystore 之后【英文标题】:ColdFusion CFHTTP I/O Exception: peer not authenticated - even after adding certs to Keystore 【发布时间】:2010-12-09 10:35:02 【问题描述】:

我目前正在与支付处理商合作。我可以从我们的服务器浏览到支付 URL,所以这不是防火墙问题,但是当我尝试使用 CFHTTP 时,我得到一个 I/O 异常:peer not authenticated。我已将他们最新的安全证书下载并安装到 cacerts 密钥库中并重新启动了 CF,但仍然遇到相同的错误。我不仅安装了提供者证书,还安装了证书链中的其他 2 个 Verisign 证书颁发机构证书。该证书是较新的 3 类扩展验证证书之一。

以前有没有人遇到过这个问题并找到了解决方案?

【问题讨论】:

这里的响应很晚,但我最终选择了 CFX_HTTP5 自定义标签,可以在 cftagstore.com/tags/cfxhttp5.cfm 找到 【参考方案1】:

我的一位同事在连接到第 3 方时遇到同样的问题后发现以下问题。

http://www.coldfusionjedi.com/index.cfm/2011/1/12/Diagnosing-a-CFHTTP-issue--peer-not-authenticated

https://www.raymondcamden.com/2011/01/12/Diagnosing-a-CFHTTP-issue-peer-not-authenticated/

我们使用了 Pete Freitag 在页面下方评论中提供的解决方案。它有效,但我认为应谨慎使用,因为它涉及动态删除和添加 JsafeJCE 提供程序的特定属性。

为了存档,这里是Pete Freitag评论的原始内容:

我进一步缩小了范围,并删除了 KeyAgreement.DiffieHellman 来自 RSA JsafeJCE 提供程序(其中 导致改为使用默认的 sun 实现)接缝 工作,并且可能对您的服务器的影响小于删除 整个供应商都会。以下是你的做法:

<cfset objSecurity = createObject("java", "java.security.Security") />
<cfset storeProvider = objSecurity.getProvider("JsafeJCE") />
<cfset dhKeyAgreement = storeProvider.getProperty("KeyAgreement.DiffieHellman")>
<!--- dhKeyAgreement=com.rsa.jsafe.provider.JSA_DHKeyAgree --->
<cfset storeProvider.remove("KeyAgreement.DiffieHellman")>

Do your http call, but pack the key agreement if you want:

<cfset storeProvider.put("KeyAgreement.DiffieHellman", dhKeyAgreement)>

我通过使用 SSLSocketFactory 创建一个 https 来解决这个问题 连接,它在堆栈跟踪中提供了更多详细信息,而不是 使用cfhttp时:

yadayadayada Caused by: java.security.InvalidKeyException: Cannot
build a secret key of algorithm TlsPremasterSecret at
com.rsa.jsafe.provider.JS_KeyAgree.engineGenerateSecret(Unknown
Source) at javax.crypto.KeyAgreement.generateSecret(DashoA13*..) at
com.sun.net.ssl.internal.ssl.DHCrypt.getAgreedSecret(DHCrypt.java:166)

如果 ColdFusion 抛出的异常少一点就好了 通用的。

【讨论】:

嘿巴里,有点困惑。在这里,您说您使用了 Pete Freitag 建议的解决方法,但在上面的评论中您说您“最终使用了 CFX_HTTP5”自定义标签。你最终的解决方案是什么?【参考方案2】:

特定于带有现代 ssl 密码的网络服务器的coldfusion 8:

我在 JDK 1.6.45 上使用了 Coldfusion 8,但在给我的只是红十字而不是图像时遇到了问题,而且 cfhttp 无法使用 ssl 连接到本地网络服务器。

我用 Coldfusion 8 重现的测试脚本是

<CFHTTP URL="https://www.onlineumfragen.com" METHOD="get" ></CFHTTP>
<CFDUMP VAR="#CFHTTP#">

这给了我“I/O 异常:对等体未通过身份验证”的非常普遍的错误。 然后,我尝试将服务器的证书(包括根证书和中间证书)添加到 java 密钥库以及冷融合密钥库,但没有任何帮助。 然后我用

调试了问题
java SSLPoke www.onlineumfragen.com 443

得到了

javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair

Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be
multiple of 64, and can only range from 512 to 1024 (inclusive)
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DashoA13*..)
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:627)
    at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:107)
    ... 10 more

然后我想到网络服务器(在我的例子中是 apache)有非常现代的 ssl 密码并且非常严格(qualys 得分 a+)并且使用超过 1024 位的强 diffie hellmann 密钥。显然,coldfusion 和 java jdk 1.6.45 无法做到这一点。 odysee 的下一步是考虑为 java 安装一个替代安全提供程序,我决定使用 bouncy castle。 另见http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/

然后我下载了

bcprov-ext-jdk15on-156.jar

来自http://www.bouncycastle.org/latest_releases.html 并安装在 C:\jdk6_45\jre\lib\ext 或您的 jdk 所在的位置,在冷融合 8 的原始安装中,它将位于 C:\JRun4\jre\lib\ext 下,但我使用位于外部的较新 jdk (1.6.45)冷融合目录。将 bcprov-ext-jdk15on-156.jar 放在 \ext 目录中非常重要(这花了我大约两个小时和一些头发;-) 然后我编辑了文件 C:\jdk6_45\jre\lib\security\java.security (使用写字板而不是 editor.exe!)并为新提供者放入一行。之后列表看起来像

#
# List of providers and their preference orders (see above):
#
security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
security.provider.2=sun.security.provider.Sun
security.provider.3=sun.security.rsa.SunRsaSign
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=sun.security.mscapi.SunMSCAPI

(见位置 1 的新的)

然后完全重启coldfusion服务。 然后就可以了

java SSLPoke www.onlineumfragen.com 443 (or of course your url!)

并享受这种感觉... 而且当然

多么美好的夜晚和多么美好的一天。希望这会(部分或全部)对那里的人有所帮助。如果您有任何问题,请通过 info ...(以上域)给我发邮件。

【讨论】:

这非常有用,但我发现如果我将 BouncyCastle 置于位置 1,我无法启动 ColdFusion 8 服务。但它在位置 2 上运行良好(在 sun.security.provider 之后。太阳)。再次感谢您为我节省了大量时间!【参考方案3】:

您是否将其添加到正确的密钥库中?请记住,ColdFusion 使用它自己的 Java 实例。我曾经在这件事上花了几个小时才想起这个事实。您想要的位于 /ColdFusion8/runtime/jre/lib/security/ 之类的地方

【讨论】:

嗨,Ryber,这是我添加它们的地方。在此之前我已经添加了其他的,它总是有效的。谢谢。 也许你错过了链上的一个证书,Java 抱怨因为它无法验证签名者的真实性? 嗨十六 Otto,我已经在链中安装了所有 3 个证书,但仍然无法正常工作!【参考方案4】:

在 CMD 中试试这个

C:\ColdFusion9\runtime\jre\bin> keytool -import -keystore ../lib/security/cacerts -alias uniquename -file certificatename.cer

注意:我们必须选择安全文件夹中存在的正确密钥库,因为 bin 中存在其他密钥库文件。如果我们将证书导入这些密钥库,它将不起作用。

【讨论】:

【参考方案5】:

我刚刚发现的内容在这篇文章中被引用:http://kb2.adobe.com/cps/400/kb400977.html 和其他一些地方经过大量挖掘。

如果您正在查看本文,您很可能已将“server.crt”证书插入到正确的根位置,并且您可能已使用命令

\ColdFusion9\runtime\jre\bin\keytool -import -v -alias someServer-cert -file someServerCertFile.crt -keystore cacerts -storepass changeit

(如果你还没有这样做,现在就去做)。 我遇到的事情是我在我的本地主机上设置了 ssl,所以在执行这些步骤之后我仍然遇到同样的错误。

事实证明,您还需要使用命令将“server.crt”插入到通常位于 /ColdFusion9/runtime/jre/lib 中的“trustStore”文件中

\ColdFusion9\runtime\jre\bin\keytool -import -v -alias someServer-cert -file someServerCertFile.cer -keystore trustStore -storepass changeit

希望这会节省一些人的时间。

【讨论】:

【参考方案6】:

我正在使用 JRun。在尝试了很多不同的事情之后,我发现了一些适用于我的设置的信息。我已经用我自己的信任库文件配置了一个 (1)HTTPS SSLService。这导致以下链接中的信息变得重要。

http://helpx.adobe.com/coldfusion/kb/import-certificates-certificate-stores-coldfusion.html

注意:如果您使用 JRun 作为底层 J2EE 服务器(无论是 服务器配置或带有 JRun 配置的 Multiserver/J2EE) 并为内部 JRun Web 服务器 (JWS) 启用 SSL,您将 需要将证书导入到定义的信任库中 用于 Secure JWS 而不是 JRE 密钥存储的 jrun.xml 文件。经过 默认情况下,该文件称为“trustStore”,通常位于 在 jrun_root/lib 下,用于具有 JRun 配置的 Multiserver/J2EE 或 cf_root/runtime/lib 用于 ColdFusion 服务器配置。你 使用相同的 Java keytool 来管理 trustStore。

这是我的 jrun.xml 文件的摘录:

<service class="jrun.servlet.http.SSLService" name="SSLService">
  <attribute name="port">8301</attribute>
  <attribute name="keyStore">/app/jrun4/cert/cfusion.jks</attribute>
  <attribute name="trustStore">/app/jrun4/cert/truststore.jks</attribute>
  <attribute name="name">SSLService</attribute>
  <attribute name="bindAddress">*</attribute>
  <attribute name="socketFactoryName">jrun.servlet.http.JRunSSLServerSocketFactory</attribute>
  <attribute name="interface">*</attribute>
  <attribute name="keyStorePassword">cfadmin</attribute>
  <attribute name="deactivated">false</attribute>
</service>

将证书导入此信任库 (/app/jrun4/cert/truststore.jks) 后,它在重新启动 ColdFusion 后工作。


(1)http://helpx.adobe.com/legacy/kb/ssl-jrun-web-server-connector.html

【讨论】:

【参考方案7】:

在 CF9 Enterprise 上将证书添加到密钥库对我不起作用。

最终使用了 CFX 标签 CFX_HTTP5

【讨论】:

【参考方案8】:

我意识到这是一个非常古老的讨论,但由于它仍然出现在搜索 CF 中“peer not authenticated”错误的顶部附近,我想与大多数人分享,简单的解决方案就是更新CF使用的JVM。 (稍后会详细介绍如何做到这一点。)

问题的原因通常是被调用的服务进行了更改,需要更高版本的 TLS 或 SSL(可能还需要更改支持的算法)。后来的 JVM 提供了这一点,而早期的 JVM 没有。由于 CF 在 JVM 上运行,因此“突然”开始失败的是来自 CF 的调用(va cfhttp、cfldap、cfmail 等)。

当然,有时需要更新证书(即使这样,您也必须小心谨慎),但并不总是需要。更新 JVM 还带来了其他好处,例如错误修复等。

唯一的挑战是了解您的 CF 版本将支持哪种 JVM。 (但即使是还在旧 CF 版本上运行的人也发现,更新 JVM CF 使用已经解决了这个问题,并且没有引起任何其他问题。)

我在 2019 年的帖子中讨论了所有这些:

https://coldfusion.adobe.com/2019/06/error-calling-cf-via-https-solved-updating-jvm/

希望对某人有所帮助。

【讨论】:

以上是关于ColdFusion CFHTTP I/O 异常:peer not authenticated - 即使在将证书添加到 Keystore 之后的主要内容,如果未能解决你的问题,请参考以下文章

SSL 的 CFHTTP 问题 - 关闭 cfhttp 的安全性?

如何在某些 java 类或包上限制 createObject()?

如何捕获 I/O 异常(确切地说是 I/O,而不是 std::exception)

ES 查询时报错 I/O 异常: Request cannot be executed; I/O reactor status: STOPPED

24.Python文件I/O异常处理&断言assert

Coldfusion输入表格和时间