- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在寻找类似于 this answer 的解决方案,但更安全。我想禁用证书验证,但仅针对单个请求(这就是我所需要的)。所以它应该做以下一项或多项
当我要求更安全的解决方案时,我真的很想知道与原始问题(分数 +46)相比,这个问题(分数 -2)有什么问题。有人可以解释一下吗?
解释我为什么需要这个:有一个有效的服务器证书,通常,它会被使用。但我需要向 localhost
发送一个请求,它也必须在开发人员机器上运行。它必须是 https
,因为不支持 http
。
最佳答案
此实用程序类基于提供的示例。使用“宽松”的 SSLContext 预配置接受所有证书的 TrustManager。如果您的本地主机 ssl 证书颁发给不同的 CN,还需要一个主机名 validator
使用 HttpsURLConnection.setSocketFactory
和 HttpsURLConnection.setHostnameVerifier
将其应用于需要“宽松”ssl 验证的每个连接。默认行为不会改变
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class RelaxedSSLContext {
// Create a trust manager that does not validate certificate chains like
public static TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
//No need to implement.
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
//No need to implement.
}
}
};
//hostname verifier. All hosts valid
public static HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
//hostname verifier. Only localhost and 127.0.0.1 valid
public static HostnameVerifier localhostValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return "localhost".equals(hostname) || "127.0.0.1".equals(hostname);
}
};
public static SSLContext getInstance() throws KeyManagementException, NoSuchAlgorithmException{
return getInstance("SSL");
}
//get a 'Relaxed' SSLContext with no trust store (all certificates are valids)
public static SSLContext getInstance(String protocol) throws KeyManagementException, NoSuchAlgorithmException{
SSLContext sc = SSLContext.getInstance(protocol);
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc;
}
}
这样使用
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(RelaxedSSLContext.getInstance().getSocketFactory());
conn.setHostnameVerifier(RelaxedSSLContext.localhostValid);
示例 1(默认)
url = "https://www.google.cop/finance";
conn = url.openConnection();
conn.connect();
int statusCode = conn.getResponseCode(); // 200
示例 2(错误的主机名)
url = "https://216.58.210.164/finance";
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(RelaxedSSLContext.allHostsValid);
conn.connect();
int statusCode = conn.getResponseCode(); //200
// ERROR 'No subject alternative names matching IP address 216.58.210.164 found' without hostnameVerifier
示例 3(链不在默认信任库中)
url = "https://www.aragon.es";
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(RelaxedSSLContext.getInstance().getSocketFactory());
conn.connect();
int statusCode = conn.getResponseCode(); //200
// ERROR 'unable to find valid certification path to requested target' without relaxedSocketFactory
我认为您的问题切题、有用且表达得当。在某些情况下,应用高安全性上下文是合适的,或者更确切地说,不是必需的。纯 HTTP 仍在使用中......
让我们分析一下您的上下文。所需的是通过 HTTPS 访问本地主机而不信任服务器身份。这意味着您要接受服务器提供的任何证书。这种情况下的安全问题是 MITM 附加(中间人)。来自(维基百科)
Attacker secretly relays and possibly alters the communication betweentwo parties who believe they are directly communicating with eachother.
但是否有可能是 MITM 攻击与本地主机的不受信任的 https 连接?
首先,在 https 中,服务器必须向客户端提供服务器证书。客户端验证证书的公钥并检查是否与本地信任库匹配。通过网络管理员的协作,可以嗅探网络并设置代理来拦截连接。但是恶意代理没有匹配的私钥,因此代理服务器可能会尝试伪造证书并提供自己的公钥。证书不会出现在客户端 trustore 上,因此连接将被拒绝。但是如果去掉truststore验证,理论上是可以进行攻击的。
但是,MITM 是否可能限制与本地主机的连接?
参见 https://security.stackexchange.com/questions/61399/are-mitm-attacks-possible-on-http-loopbacks
在一般情况下这是不可能的,但是具有机器根访问权限的攻击者可以更改 DNS 并将请求重定向到恶意代理。即使使用 127.0.0.1,如果应用程序有配置连接端口的方法也是可能的。
偏执的解决方案可能是硬编码服务器连接 url、端口甚至 trustore。但是你说的是开发环境中的 localhost,所以我想我们可以放松一点
关于java - 为单个连接禁用 SSLHandshakeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37724901/
在日志中看到此错误消息,任何人都可以告诉发生了什么 “javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorExcep
我获得了一个 jar 文件,但无法访问代码(或无法修改)和一个 .cer ca 证书文件。 运行jar文件时;我收到此错误(我输入了 placeholder.hostname.com ): org.s
我需要忽略 PKIX 路径构建异常 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PK
我正在尝试使用 HttpsURLConnection 与网站建立 HTTPS 连接,然后执行 PUT 请求。当我尝试从 HttpsURLConnection.getOutputStream() 创建
我的 SSL 握手有一个小问题,当我尝试启动 GET 请求时,服务器返回 java.lang.RuntimeException: javax.net.ssl.SSLHandshakeException
非常感谢您阅读这篇文章,我们将不胜感激! 我正在尝试使用服务帐户在云端硬盘中列出和创建一个文本文件。已经生成了一个服务帐户,下载了 p12 文件也为该帐户启用了 Drive api。但是我收到了 SS
我使用 Retrofit2。添加服务器端 SSL 后请求不会执行。 onFailure 方法获取下一个 Throwable - javax.net.ssl.SSLHandshakeException:
这个问题在这里已经有了答案: Resolving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorExce
我正在尝试使用自签名证书访问本地 https 站点。我修改了主机文件并为我的本地站点分配了一个 IP 地址;我用来访问网站的代码: String httpsURL = "https://test-s
我有一个服务到服务的连接,它间歇性地从 Jersey 客户端抛出 SSLHandshakeExceptions。 public static class MyClientFilter extends
我正在尝试创建端点以将我的谷歌应用引擎连接到我的 android 应用程序。我正在学习本教程 https://developers.google.com/eclipse/docs/endpoints-
使用这样的代码: val html = Source.fromURL("https://scans.io/json") 获取异常: Exception in thread "main" javax.n
我正在尝试从 Java 9 测试新的 HttpClient。出于测试目的,我正在使用 https://jsonplaceholder.typicode.com 提供的 api。 .但是,我收到握手异常
我正在寻找类似于 this answer 的解决方案,但更安全。我想禁用证书验证,但仅针对单个请求(这就是我所需要的)。所以它应该做以下一项或多项 完成一个请求后返回安全状态 仅对给定的 URL 禁用
当我访问 wsdl url 时,我在 android 中遇到异常 javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathVal
当我尝试使用 Java 代码以编程方式下载文件时,出现异常: Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.s
我们有一个 JavaFX 应用程序在 https 安全资源上调用我们的后端。该应用程序连续向同一个 url 发出数百个请求,以从服务器获取数据。 这通常没有问题,但现在我们有一个客户在连接到资源时报告
我正在尝试从 java 访问我的 api,但出现以下错误: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate
我最近在我的网站上添加了 SSL,可以通过 https 访问它。现在,当我的 Java 应用程序尝试向我的网站发出请求并使用缓冲读取器从中读取时,它会生成此堆栈跟踪 我没有使用自签名证书,该证书来自
我有两个代码示例,一个使用 Rest Template 和其他 Apache HttpClient 将 json 发布到我们的内部 https Web 服务。 我们的服务负载均衡器端存在这个已知的 S
我是一名优秀的程序员,十分优秀!