- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用自签名证书进行 SSL 双向身份验证。我为 client(client-keystore.jks) 和 server(server-keystore.jks) 创建了两个 keystore ,从两个 keystore 导出证书并将客户端证书导入到服务器 keystore 和服务器证书到客户端 keystore 。并更新了 server.xml 中所需的连接器条目,将两个证书添加到 java 信任库 cacerts。
Java 客户端代码:
KeyStore trustStore = KeyStore.getInstance("JKS", "SUN");
trustStore.load(SSLImplemetation.class.getResourceAsStream("C:/Program Files/Java/jdk1.7.0_79/jre/lib/security/cacerts"), "changeit".toCharArray());
String alg = KeyManagerFactory.getDefaultAlgorithm();
TrustManagerFactory fac = TrustManagerFactory.getInstance(alg);
fac.init(trustStore);
KeyStore keystore = KeyStore.getInstance("JKS", "SUN");
keystore.load(SSLImplemetation.class.getResourceAsStream("<dir path>/client-keystore.jks"), "test".toCharArra());
String keyAlg = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory keyFac = KeyManagerFactory.getInstance(keyAlg);
keyFac.init(keystore, "test".toCharArray());
SSLContext ctx = SSLContext.getInstance("TLS", "SunJSSE");
ctx.init(keyFac.getKeyManagers(),fac.getTrustManagers(), new SecureRandom());
SslContextedSecureProtocolSocketFactory secureProtocolSocketFactory = new SslContextedSecureProtocolSocketFactory(ctx);
Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory) secureProtocolSocketFactory, 8443));
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpPost request = new HttpPost("<rest service url>");
JSONObject obj = new JSONObject();
StringEntity params =new StringEntity(obj.toString());
request.addHeader("content-type", "application/json");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
System.out.println(response.getStatusLine());
服务器.xml:
<Connector
protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" maxThreads="200" scheme="https" secure="true" SSLEnabled="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="<dir path>/server-keystore.jks" keystorePass="test"
truststoreFile="C:/Program Files/Java/jdk1.7.0_79/jre/lib/security/cacerts"
truststorePass="changeit" />
我是 SSl 的新手,所以有点困惑。任何帮助将不胜感激。
最佳答案
下面的代码对我来说工作正常,在创建两个客户端和服务器 keystore 并将证书都放入 java truststore 之后,我使用下面的代码进行 SSL 相互身份验证。
static final private String KEY_STORE = "D:/sslcertificates/client-keystore.jks";
static final private String KEY_STORE_TYPE = "JKS";
static final private String KEY_STORE_PASS = "test";
public static void main(String[] args) throws JSONException{
try {
URL url = new URL("<rest service url>");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname,
javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("<hostname>")) {
return true;
}
return false;
}
});
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
try
{
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509","SunJSSE");
KeyStore ks = KeyStore.getInstance(KEY_STORE_TYPE);
File cert = new File(KEY_STORE);
InputStream stream = new FileInputStream(cert);
ks.load(stream, KEY_STORE_PASS.toCharArray());
stream.close();
kmf.init(ks,KEY_STORE_PASS.toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(),null, new SecureRandom());
SSLSocketFactory factory = context.getSocketFactory();
conn.setSSLSocketFactory(factory);
}
catch(Exception e)
{
System.out.println(e);
}
JSONObject obj = new JSONObject();
obj.put("id","abc");
obj.put("name","surya");
obj.put( "domain","IT");
String input=obj.toString();
//send request to server....
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
System.out.println("Response code: "+conn.getResponseCode());
System.out.println("Response message: "+conn.getResponseMessage());
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
服务器.xml
<Connector
protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" maxThreads="200" scheme="https" secure="true" SSLEnabled="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="<dir path>/server-keystore.jks" keystorePass="test"/>
注意:在 HttpsURLConnection 对象中设置 HostnameVerifier,客户端和服务器 keystore 的 CN 应该是主机名。
如果有更好的解决方案,请提出建议。
关于java - 面对 javax.net.ssl.SSLHandshakeException : Received fatal alert: bad_certificate issue while implementing SSL two way authentication,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36760089/
在日志中看到此错误消息,任何人都可以告诉发生了什么 “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
我是一名优秀的程序员,十分优秀!