CFHTTP 无法找到请求目标的有效证书路径
CFHTTP unable to find valid certification path to requested target
我正在寻找从网站上抓取数据的方法,其他 https 网站可以正常工作,上周还可以,但现在失败了
<cfhttp url="https://www.cliftoncameras.co.uk/all-brands-and-types-of-used-cameras/"></cfhttp>
如果我 运行 cfhttp
转储
Exception: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
我已经尝试了 运行 最新的 JRE 版本 12 - 没有变化
https://helpx.adobe.com/coldfusion/kb/import-certificates-certificate-stores-coldfusion.html
恢复为 CF 原始 JRE,下载目标 SSL 证书并使用密钥工具安装它 - 无变化
c:\ColdFusion2018\jre\bin\keytool -import -keystore cacerts -alias
cliftoncameras -file
c:\ColdFusion2018\jre\lib\security\cliftoncameras.cer
我将 CFAdmin 中的 websocket 更改为代理 - 无变化
我确实每次都重新启动了 CF 应用程序服务器。
我还能做什么?
我之前也曾在 Java 和 Coldfusion 网站上看到过这个 java.security.cert.CertPathBuilderException
错误,这些网站在常规浏览器中加载正常,但即使在将证书添加到 CF 密钥库后,cfhttp 仍然出现错误并重新启动。
当目标站点服务器证书配置存在信任链问题时会发生这种情况 - 当一个或多个信任链路径要求浏览器执行 "extra download" 证书时。这可能是因为单个信任链路径中缺少中间证书,或者因为信任链中有多个分支具有不同的指纹,并且来自一个或多个分支的一个或多个证书未被提供。
如果您 运行 通过像 ssllabs.com 这样的 SSL 分析器访问目标站点 - 例如
https://globalsign.ssllabs.com/analyze.html?d=www.cliftoncameras.co.uk&hideResults=on - 你会看到他们的中间证书 Starfield Secure Certificate Authority - G2
没有被他们的服务器提供服务,这迫使客户端执行 "extra download" - 这对大多数适当的人来说不是问题浏览器,但 cfhttp 使用的 Java 客户端需要服务器直接提供几乎所有中间证书和根证书。直到几年前,大多数移动操作系统都是一样的。
因此,理想的解决方案是联系 cliftoncameras 并让他们的服务器管理员安装正确的 Starfield 中级证书,以便正确提供服务。
您这边可能的解决方法是在您的 CF 密钥库中安装 Starfield Secure Certificate Authority - G2
中间证书。
如果你不能让密钥库工作,也许你会想试试这个。
创建专用命令行可执行文件 (.exe),它将读取网页并将源代码保存到文本文件中。然后您可以使用 ColdFusion 读取文件并处理数据。
这是 ColdFusion 代码:
<cfscript>
_execPath = "c:/bin/clifton.exe";
_filePath = "c:/bin/clifton.txt";
// run your command-line app (clifton.exe)
cfexecute(name="#_execPath#");
// wait for the file
do {
sleep(100);
} while ( not fileExists(_filePath) )
// wait for write to finish
do {
sleep(100);
_fileInfo = getFileInfo(_filePath);
writeOutput(" ## ");
cfflush();
} while ( _fileInfo.size eq 0 || dateDiff("s", _fileInfo.lastmodified, now()) lte 3 )
writeOutput("<hr />")
_result = fileRead(_filePath);
writeDump(_result);
</cfscript>
如您所见,它依赖于 clifton.exe
并读取 clifton.txt
(clifton.txt 是执行 clifton.exe 的结果)。
制作方法clifton.exe
您将使用 Dart SDK 和 dart2native
工具在您的开发计算机上创建可执行文件。您可以在生产服务器上独立部署可执行文件(您不需要在生产环境中安装 Dart SDK)。
- 在您的 C 盘上创建一个
bin
文件夹。
- 从 https://ssl-ccp.secureserver.net/repository/?origin=CALLISTO 下载证书
sfig2.crt.pem (PEM)
并将其保存在 c:\bin
. 中
- 在
c:\bin
中使用以下代码创建一个文本文件 clifton.dart
:
// clifton.dart
import 'dart:convert';
import 'dart:io';
main() {
//
const String _certFilePath = 'c:/bin/sfig2.crt.pem';
const String _responseFilePath = 'c:/bin/clifton.txt';
const String _uri =
'https://www.cliftoncameras.co.uk/all-brands-and-types-of-used-cameras/';
final File _file = new File(_responseFilePath);
final IOSink _sink = _file.openWrite();
final SecurityContext _context = new SecurityContext();
_context.setTrustedCertificates(_certFilePath);
final HttpClient _client = new HttpClient(context: _context);
saveSourceToFile(_client, _uri, _sink);
_client.close();
//
}
// get web page source then write it to file
void saveSourceToFile(HttpClient _client, String _uri, IOSink _sink) {
//
_client
.getUrl(Uri.parse(_uri))
.then((req) => req.close())
.then((res) => res.transform(Utf8Decoder()).listen((data) {
// as data is received write to file
_sink.write(data);
}, onDone: () {
_sink.close();
}));
//
}
- 从 https://dart.dev/
下载并安装 Dart SDK
- 打开一个终端 window 并使用
dart --version
测试 Dart 的安装(您应该可以 运行 从任何文件夹中安装 dart,如果需要,将 dart 添加到您的 PATH 中)
- 在终端 window 中,使用
cd c:\bin
将目录更改为 c:\bin
- 接下来,运行
dart2native clifton.dart -o clifton.exe
- 如果编译顺利,你应该在
c:\bin
中包含三个文件:clifton.dart
、clifton.exe
和证书 sfig2.crt.pem
.
- 如果您愿意,可以在终端 window 中测试 运行
clifton.exe
,这应该会创建 clifton.txt
文件。
- 测试调用
clifton.exe
的ColdFusion页面,等待clifton.txt
然后输出内容。
如果在生产环境中部署,则需要文件 clifton.exe
和 sfig2.crt.pem
(证书)。
祝你好运!
在我的开发平台上添加了
-Dcom.sun.security.enableAIAcaIssuers=true
到ColdFusion2018\cfusion\bin\jvm.config
文件中的java.args
然后重启了CF应用服务器,现在我的CFHTTP调用成功了。
感谢@agreax 提供此解决方案
感谢@sevroberts,他的回答可能是正确的,尽管我无法让它工作。生产主机将 SSL 证书安装到密钥库中,并通过这种方式成功解析。他们说:
If you use FireFox browser and click on the lock icon when browsing the URL you are wanting to have the cfhttp request access you can then get the more info and click the View Certificate option.
You will need to download the PEM (cert) not the Chain. Once downloaded, you need to run the keytool in order to import it to the keystore.
If you are using the default JRE within your JVM for ColdFusion you will need to install a JDK to your development machine.
You can see the details and steps we have listed on our wiki regarding the commands from the command prompt to import the SSL into the store.
https://wiki.hostek.com/ColdFusion_Tips_%26_Tricks#Fixing_cfhttp_Connection_Failures_with_Keytool
感谢@alexbaban 他的解决方法,虽然它有效,但由于需要使用标签 cfexecute,我无法实施该解决方案。
我正在寻找从网站上抓取数据的方法,其他 https 网站可以正常工作,上周还可以,但现在失败了
<cfhttp url="https://www.cliftoncameras.co.uk/all-brands-and-types-of-used-cameras/"></cfhttp>
如果我 运行 cfhttp
转储Exception: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
我已经尝试了 运行 最新的 JRE 版本 12 - 没有变化
https://helpx.adobe.com/coldfusion/kb/import-certificates-certificate-stores-coldfusion.html
恢复为 CF 原始 JRE,下载目标 SSL 证书并使用密钥工具安装它 - 无变化
c:\ColdFusion2018\jre\bin\keytool -import -keystore cacerts -alias cliftoncameras -file c:\ColdFusion2018\jre\lib\security\cliftoncameras.cer
我将 CFAdmin 中的 websocket 更改为代理 - 无变化
我确实每次都重新启动了 CF 应用程序服务器。
我还能做什么?
我之前也曾在 Java 和 Coldfusion 网站上看到过这个 java.security.cert.CertPathBuilderException
错误,这些网站在常规浏览器中加载正常,但即使在将证书添加到 CF 密钥库后,cfhttp 仍然出现错误并重新启动。
当目标站点服务器证书配置存在信任链问题时会发生这种情况 - 当一个或多个信任链路径要求浏览器执行 "extra download" 证书时。这可能是因为单个信任链路径中缺少中间证书,或者因为信任链中有多个分支具有不同的指纹,并且来自一个或多个分支的一个或多个证书未被提供。
如果您 运行 通过像 ssllabs.com 这样的 SSL 分析器访问目标站点 - 例如
https://globalsign.ssllabs.com/analyze.html?d=www.cliftoncameras.co.uk&hideResults=on - 你会看到他们的中间证书 Starfield Secure Certificate Authority - G2
没有被他们的服务器提供服务,这迫使客户端执行 "extra download" - 这对大多数适当的人来说不是问题浏览器,但 cfhttp 使用的 Java 客户端需要服务器直接提供几乎所有中间证书和根证书。直到几年前,大多数移动操作系统都是一样的。
因此,理想的解决方案是联系 cliftoncameras 并让他们的服务器管理员安装正确的 Starfield 中级证书,以便正确提供服务。
您这边可能的解决方法是在您的 CF 密钥库中安装 Starfield Secure Certificate Authority - G2
中间证书。
如果你不能让密钥库工作,也许你会想试试这个。
创建专用命令行可执行文件 (.exe),它将读取网页并将源代码保存到文本文件中。然后您可以使用 ColdFusion 读取文件并处理数据。
这是 ColdFusion 代码:
<cfscript>
_execPath = "c:/bin/clifton.exe";
_filePath = "c:/bin/clifton.txt";
// run your command-line app (clifton.exe)
cfexecute(name="#_execPath#");
// wait for the file
do {
sleep(100);
} while ( not fileExists(_filePath) )
// wait for write to finish
do {
sleep(100);
_fileInfo = getFileInfo(_filePath);
writeOutput(" ## ");
cfflush();
} while ( _fileInfo.size eq 0 || dateDiff("s", _fileInfo.lastmodified, now()) lte 3 )
writeOutput("<hr />")
_result = fileRead(_filePath);
writeDump(_result);
</cfscript>
如您所见,它依赖于 clifton.exe
并读取 clifton.txt
(clifton.txt 是执行 clifton.exe 的结果)。
制作方法
clifton.exe
您将使用 Dart SDK 和 dart2native
工具在您的开发计算机上创建可执行文件。您可以在生产服务器上独立部署可执行文件(您不需要在生产环境中安装 Dart SDK)。
- 在您的 C 盘上创建一个
bin
文件夹。 - 从 https://ssl-ccp.secureserver.net/repository/?origin=CALLISTO 下载证书
sfig2.crt.pem (PEM)
并将其保存在c:\bin
. 中
- 在
c:\bin
中使用以下代码创建一个文本文件clifton.dart
:
// clifton.dart
import 'dart:convert';
import 'dart:io';
main() {
//
const String _certFilePath = 'c:/bin/sfig2.crt.pem';
const String _responseFilePath = 'c:/bin/clifton.txt';
const String _uri =
'https://www.cliftoncameras.co.uk/all-brands-and-types-of-used-cameras/';
final File _file = new File(_responseFilePath);
final IOSink _sink = _file.openWrite();
final SecurityContext _context = new SecurityContext();
_context.setTrustedCertificates(_certFilePath);
final HttpClient _client = new HttpClient(context: _context);
saveSourceToFile(_client, _uri, _sink);
_client.close();
//
}
// get web page source then write it to file
void saveSourceToFile(HttpClient _client, String _uri, IOSink _sink) {
//
_client
.getUrl(Uri.parse(_uri))
.then((req) => req.close())
.then((res) => res.transform(Utf8Decoder()).listen((data) {
// as data is received write to file
_sink.write(data);
}, onDone: () {
_sink.close();
}));
//
}
- 从 https://dart.dev/ 下载并安装 Dart SDK
- 打开一个终端 window 并使用
dart --version
测试 Dart 的安装(您应该可以 运行 从任何文件夹中安装 dart,如果需要,将 dart 添加到您的 PATH 中) - 在终端 window 中,使用
cd c:\bin
将目录更改为 - 接下来,运行
dart2native clifton.dart -o clifton.exe
- 如果编译顺利,你应该在
c:\bin
中包含三个文件:clifton.dart
、clifton.exe
和证书sfig2.crt.pem
. - 如果您愿意,可以在终端 window 中测试 运行
clifton.exe
,这应该会创建clifton.txt
文件。 - 测试调用
clifton.exe
的ColdFusion页面,等待clifton.txt
然后输出内容。
c:\bin
如果在生产环境中部署,则需要文件 clifton.exe
和 sfig2.crt.pem
(证书)。
祝你好运!
在我的开发平台上添加了
-Dcom.sun.security.enableAIAcaIssuers=true
到ColdFusion2018\cfusion\bin\jvm.config
文件中的java.args然后重启了CF应用服务器,现在我的CFHTTP调用成功了。
感谢@agreax 提供此解决方案
感谢@sevroberts,他的回答可能是正确的,尽管我无法让它工作。生产主机将 SSL 证书安装到密钥库中,并通过这种方式成功解析。他们说:
If you use FireFox browser and click on the lock icon when browsing the URL you are wanting to have the cfhttp request access you can then get the more info and click the View Certificate option. You will need to download the PEM (cert) not the Chain. Once downloaded, you need to run the keytool in order to import it to the keystore.
If you are using the default JRE within your JVM for ColdFusion you will need to install a JDK to your development machine. You can see the details and steps we have listed on our wiki regarding the commands from the command prompt to import the SSL into the store. https://wiki.hostek.com/ColdFusion_Tips_%26_Tricks#Fixing_cfhttp_Connection_Failures_with_Keytool
感谢@alexbaban 他的解决方法,虽然它有效,但由于需要使用标签 cfexecute,我无法实施该解决方案。