gpt4 book ai didi

java - 面对 javax.net.ssl.SSLHandshakeException : Received fatal alert: bad_certificate issue while implementing SSL two way authentication

转载 作者:太空宇宙 更新时间:2023-11-03 13:37:01 26 4
gpt4 key购买 nike

我正在使用自签名证书进行 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com