我正在构建一个应用程序,它会定期检查一些 RSS 提要是否有新内容。其中一些提要只能通过 https 访问,而另一些提要具有自签名或以某种方式损坏的证书。我希望能够始终检查它们。
请注意,安全性在此应用程序中不是问题,目标是以最小的努力访问内容。
我正在使用此代码来规避大多数证书问题:
/**
* Sets timeout values and user agent header, and ignores self signed ssl
* certificates to enable maximum coverage
*
* @param con
* @return
*/
public static URLConnection configureConnection(URLConnection con)
{
con.setRequestProperty(
"User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
con.setConnectTimeout(30000);
con.setReadTimeout(40000);
if (con instanceof HttpsURLConnection)
{
HttpsURLConnection conHttps = (HttpsURLConnection) con;
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
{
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
{
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
{
}
} };
HostnameVerifier allHostsValid = new HostnameVerifier()
{
@Override
public boolean verify(String arg0, SSLSession arg1)
{
return true;
}
};
// Install the all-trusting trust manager
try
{
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
con = conHttps;
} catch (Exception e)
{
}
}
return con;
}
这适用于大多数网站,但在一个网站上我仍然遇到此异常:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification pat
h to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1715)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:257)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:251)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1168)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:609)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:545)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:963)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1208)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1235)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1219)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:440)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1139)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:397)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
at crawler.RSSReader.getNewArticles(RSSReader.java:53)
at crawler.Crawler.fetchFeed(Crawler.java:187)
at crawler.Crawler.main(Crawler.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:622)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:324)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:224)
at sun.security.validator.Validator.validate(Validator.java:235)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:147)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:230)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1147)
... 20 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:197)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:255)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:319)
有谁知道我该如何解决这个问题?
最佳答案
here 有一个解决方案这优雅地为我工作。打电话
SSLUtilities.trustAllHostnames();
SSLUtilities.trustAllHttpsCertificates();
在您的 SSL 连接之前。
您还可以通过在 Internet 上搜索 java ssl trustall 来获取更多解决方案。
这是该解决方案的副本(以防将来链接断开):
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* This class provide various static methods that relax X509 certificate and
* hostname verification while using the SSL over the HTTP protocol.
*
* @author Francis Labrie
*/
public final class SSLUtilities {
/**
* Hostname verifier for the Sun's deprecated API.
*
* @deprecated see {@link #_hostnameVerifier}.
*/
private static com.sun.net.ssl.HostnameVerifier __hostnameVerifier;
/**
* Thrust managers for the Sun's deprecated API.
*
* @deprecated see {@link #_trustManagers}.
*/
private static com.sun.net.ssl.TrustManager[] __trustManagers;
/**
* Hostname verifier.
*/
private static HostnameVerifier _hostnameVerifier;
/**
* Thrust managers.
*/
private static TrustManager[] _trustManagers;
/**
* Set the default Hostname Verifier to an instance of a fake class that
* trust all hostnames. This method uses the old deprecated API from the
* com.sun.ssl package.
*
* @deprecated see {@link #_trustAllHostnames()}.
*/
private static void __trustAllHostnames() {
// Create a trust manager that does not validate certificate chains
if(__hostnameVerifier == null) {
__hostnameVerifier = new _FakeHostnameVerifier();
} // if
// Install the all-trusting host name verifier
com.sun.net.ssl.HttpsURLConnection.
setDefaultHostnameVerifier(__hostnameVerifier);
} // __trustAllHttpsCertificates
/**
* Set the default X509 Trust Manager to an instance of a fake class that
* trust all certificates, even the self-signed ones. This method uses the
* old deprecated API from the com.sun.ssl package.
*
* @deprecated see {@link #_trustAllHttpsCertificates()}.
*/
private static void __trustAllHttpsCertificates() {
com.sun.net.ssl.SSLContext context;
// Create a trust manager that does not validate certificate chains
if(__trustManagers == null) {
__trustManagers = new com.sun.net.ssl.TrustManager[]
{new _FakeX509TrustManager()};
} // if
// Install the all-trusting trust manager
try {
context = com.sun.net.ssl.SSLContext.getInstance("SSL");
context.init(null, __trustManagers, new SecureRandom());
} catch(GeneralSecurityException gse) {
throw new IllegalStateException(gse.getMessage());
} // catch
com.sun.net.ssl.HttpsURLConnection.
setDefaultSSLSocketFactory(context.getSocketFactory());
} // __trustAllHttpsCertificates
/**
* Return true if the protocol handler property java.
* protocol.handler.pkgs is set to the Sun's com.sun.net.ssl.
* internal.www.protocol deprecated one, false
* otherwise.
*
* @return true if the protocol handler
* property is set to the Sun's deprecated one, false
* otherwise.
*/
private static boolean isDeprecatedSSLProtocol() {
return("com.sun.net.ssl.internal.www.protocol".equals(System.
getProperty("java.protocol.handler.pkgs")));
} // isDeprecatedSSLProtocol
/**
* Set the default Hostname Verifier to an instance of a fake class that
* trust all hostnames.
*/
private static void _trustAllHostnames() {
// Create a trust manager that does not validate certificate chains
if(_hostnameVerifier == null) {
_hostnameVerifier = new FakeHostnameVerifier();
} // if
// Install the all-trusting host name verifier:
HttpsURLConnection.setDefaultHostnameVerifier(_hostnameVerifier);
} // _trustAllHttpsCertificates
/**
* Set the default X509 Trust Manager to an instance of a fake class that
* trust all certificates, even the self-signed ones.
*/
private static void _trustAllHttpsCertificates() {
SSLContext context;
// Create a trust manager that does not validate certificate chains
if(_trustManagers == null) {
_trustManagers = new TrustManager[] {new FakeX509TrustManager()};
} // if
// Install the all-trusting trust manager:
try {
context = SSLContext.getInstance("SSL");
context.init(null, _trustManagers, new SecureRandom());
} catch(GeneralSecurityException gse) {
throw new IllegalStateException(gse.getMessage());
} // catch
HttpsURLConnection.setDefaultSSLSocketFactory(context.
getSocketFactory());
} // _trustAllHttpsCertificates
/**
* Set the default Hostname Verifier to an instance of a fake class that
* trust all hostnames.
*/
public static void trustAllHostnames() {
// Is the deprecated protocol setted?
if(isDeprecatedSSLProtocol()) {
__trustAllHostnames();
} else {
_trustAllHostnames();
} // else
} // trustAllHostnames
/**
* Set the default X509 Trust Manager to an instance of a fake class that
* trust all certificates, even the self-signed ones.
*/
public static void trustAllHttpsCertificates() {
// Is the deprecated protocol setted?
if(isDeprecatedSSLProtocol()) {
__trustAllHttpsCertificates();
} else {
_trustAllHttpsCertificates();
} // else
} // trustAllHttpsCertificates
/**
* This class implements a fake hostname verificator, trusting any host
* name. This class uses the old deprecated API from the com.sun.
* ssl package.
*
* @author Francis Labrie
*
* @deprecated see {@link SSLUtilities.FakeHostnameVerifier}.
*/
public static class _FakeHostnameVerifier
implements com.sun.net.ssl.HostnameVerifier {
/**
* Always return true, indicating that the host name is an
* acceptable match with the server's authentication scheme.
*
* @param hostname the host name.
* @param session the SSL session used on the connection to
* host.
* @return the true boolean value
* indicating the host name is trusted.
*/
public boolean verify(String hostname, String session) {
return(true);
} // verify
} // _FakeHostnameVerifier
/**
* This class allow any X509 certificates to be used to authenticate the
* remote side of a secure socket, including self-signed certificates. This
* class uses the old deprecated API from the com.sun.ssl
* package.
*
* @author Francis Labrie
*
* @deprecated see {@link SSLUtilities.FakeX509TrustManager}.
*/
public static class _FakeX509TrustManager
implements com.sun.net.ssl.X509TrustManager {
/**
* Empty array of certificate authority certificates.
*/
private static final X509Certificate[] _AcceptedIssuers =
new X509Certificate[] {};
/**
* Always return true, trusting for client SSL
* chain peer certificate chain.
*
* @param chain the peer certificate chain.
* @return the true boolean value
* indicating the chain is trusted.
*/
public boolean isClientTrusted(X509Certificate[] chain) {
return(true);
} // checkClientTrusted
/**
* Always return true, trusting for server SSL
* chain peer certificate chain.
*
* @param chain the peer certificate chain.
* @return the true boolean value
* indicating the chain is trusted.
*/
public boolean isServerTrusted(X509Certificate[] chain) {
return(true);
} // checkServerTrusted
/**
* Return an empty array of certificate authority certificates which
* are trusted for authenticating peers.
*
* @return a empty array of issuer certificates.
*/
public X509Certificate[] getAcceptedIssuers() {
return(_AcceptedIssuers);
} // getAcceptedIssuers
} // _FakeX509TrustManager
/**
* This class implements a fake hostname verificator, trusting any host
* name.
*
* @author Francis Labrie
*/
public static class FakeHostnameVerifier implements HostnameVerifier {
/**
* Always return true, indicating that the host name is
* an acceptable match with the server's authentication scheme.
*
* @param hostname the host name.
* @param session the SSL session used on the connection to
* host.
* @return the true boolean value
* indicating the host name is trusted.
*/
public boolean verify(String hostname,
javax.net.ssl.SSLSession session) {
return(true);
} // verify
} // FakeHostnameVerifier
/**
* This class allow any X509 certificates to be used to authenticate the
* remote side of a secure socket, including self-signed certificates.
*
* @author Francis Labrie
*/
public static class FakeX509TrustManager implements X509TrustManager {
/**
* Empty array of certificate authority certificates.
*/
private static final X509Certificate[] _AcceptedIssuers =
new X509Certificate[] {};
/**
* Always trust for client SSL chain peer certificate
* chain with any authType authentication types.
*
* @param chain the peer certificate chain.
* @param authType the authentication type based on the client
* certificate.
*/
public void checkClientTrusted(X509Certificate[] chain,
String authType) {
} // checkClientTrusted
/**
* Always trust for server SSL chain peer certificate
* chain with any authType exchange algorithm types.
*
* @param chain the peer certificate chain.
* @param authType the key exchange algorithm used.
*/
public void checkServerTrusted(X509Certificate[] chain,
String authType) {
} // checkServerTrusted
/**
* Return an empty array of certificate authority certificates which
* are trusted for authenticating peers.
*
* @return a empty array of issuer certificates.
*/
public X509Certificate[] getAcceptedIssuers() {
return(_AcceptedIssuers);
} // getAcceptedIssuers
} // FakeX509TrustManager
} // SSLUtilities
关于java - 什么是完全忽略带有 java url 连接的 ssl 的简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21257455/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我打算为ruby脚本创建一个安装程序,但我希望能够确保机器安装了RVM。有没有一种方法可以完全离线安装RVM并且不引人注目(通过不引人注目,就像创建一个可以做所有事情的脚本而不是要求用户向他们的bash_profile或bashrc添加一些东西)我不是要脚本本身,只是一个关于如何走这条路的快速指针(如果可能的话)。我们还研究了这个很有帮助的问题:RVM-isthereawayforsimpleofflineinstall?但有点误导,因为答案只向我们展示了如何离线在RVM中安装ruby。我们需要能够离线安装RVM本身,并查看脚本https://raw.github.com/wayn