面临javax.net.ssl.SSLHandshakeException:在实现ssl双向身份验证时收到致命警报:错误的\u证书问题

面临javax.net.ssl.SSLHandshakeException:在实现ssl双向身份验证时收到致命警报:错误的\u证书问题,java,ssl,network-programming,openssl,keytool,Java,Ssl,Network Programming,Openssl,Keytool,我正在使用自签名证书进行SSL双向身份验证。 我已经为客户机(client keystore.jks)和服务器(server keystore.jks)创建了两个密钥库,将密钥库中的证书导出,将客户机证书导入服务器密钥库,将服务器证书导入客户机密钥库。并更新了server.xml中所需的连接器条目,将这两个证书都添加到java信任存储cacerts Java客户端代码: KeyStore trustStore = KeyStore.getInstance("JKS", "SUN");

我正在使用自签名证书进行SSL双向身份验证。 我已经为客户机(client keystore.jks)服务器(server keystore.jks)创建了两个密钥库,将密钥库中的证书导出,将客户机证书导入服务器密钥库,将服务器证书导入客户机密钥库。并更新了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());
keystoretruststore=KeyStore.getInstance(“JKS”、“SUN”);
load(SSLImplemetation.class.getResourceAsStream(“C:/ProgramFiles/Java/jdk1.7.079/jre/lib/security/cacerts”),“changeit.toCharArray());
字符串alg=KeyManagerFactory.getDefaultAlgorithm();
TrustManagerFactory fac=TrustManagerFactory.getInstance(alg);
工厂初始化(托管库);
KeyStore KeyStore=KeyStore.getInstance(“JKS”、“SUN”);
load(sslimplementation.class.getResourceAsStream(“/client keystore.jks”),“test.toCharArra());
字符串keyAlg=KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory keyFac=KeyManagerFactory.getInstance(keyAlg);
init(密钥库,“test”.toCharArray());
SSLContext ctx=SSLContext.getInstance(“TLS”、“SunJSSE”);
init(keyFac.getKeyManagers(),fac.getTrustManagers(),new SecureRandom());
SslContextedSecureProtocolSocketFactory secureProtocolSocketFactory=新的SslContextedSecureProtocolSocketFactory(ctx);
协议注册协议(“https”,新协议(“https”,(ProtocolSocketFactory)secureProtocolSocketFactory,8443));
CloseableHttpClient httpClient=HttpClientBuilder.create().build();
HttpPost请求=新的HttpPost(“”);
JSONObject obj=新的JSONObject();
StringEntity参数=新的StringEntity(obj.toString());
addHeader(“内容类型”、“应用程序/json”);
请求.setEntity(参数);
HttpResponse response=httpClient.execute(请求);
System.out.println(response.getStatusLine());
server.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新手,所以有点困惑。
任何帮助都将不胜感激。

下面的代码对我来说很好,在创建了两个客户端和服务器密钥库并将这两个证书放入java信任库之后,我使用下面的代码进行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();
static final private String KEY_STORE=“D:/sslcertificates/client keystore.jks”;
静态最终私有字符串密钥\u存储\u TYPE=“JKS”;
静态最终私有字符串密钥\u存储\u通过=“测试”;
公共静态void main(字符串[]args)抛出JSONException{
试一试{
URL=新URL(“”);
HttpsURLConnection conn=(HttpsURLConnection)url.openConnection();
conn.setHostnameVerifier(新的HostnameVerifier(){

公共布尔验证(字符串主机名,
javax.net.ssl.SSLSession(会话){
if(hostname.equals(“”){
返回true;
}
返回false;
}
});
连接设置输出(真);
conn.setRequestMethod(“POST”);
conn.setRequestProperty(“内容类型”、“应用程序/json”);
尝试
{
KeyManagerFactory kmf=KeyManagerFactory.getInstance(“SunX509”、“SunJSSE”);
KeyStore ks=KeyStore.getInstance(密钥存储类型);
文件证书=新文件(密钥存储);
InputStream=新文件InputStream(证书);
加载(stream,KEY\u STORE\u PASS.toCharArray());
stream.close();
kmf.init(ks,KEY\u STORE\u PASS.toCharArray());
SSLContext context=SSLContext.getInstance(“TLS”);
init(kmf.getKeyManager(),null,new SecureRandom());
SSLSocketFactory=context.getSocketFactory();
连接装置插座工厂(工厂);
}
捕获(例外e)
{
系统输出打印ln(e);
}
JSONObject obj=新的JSONObject();
实物期权(“id”、“abc”);
obj.put(“名称”、“苏利亚”);
目标投入(“领域”、“IT”);
字符串输入=obj.toString();
//将请求发送到服务器。。。。
OutputStream os=conn.getOutputStream();
write(input.getBytes());
os.flush();
BufferedReader br=新的BufferedReader(新的InputStreamReader(
(conn.getInputStream());
字符串输出;
System.out.println(“从服务器输出…”\n);
而((output=br.readLine())!=null){
系统输出打印项次(输出);
}
System.out.println(“响应代码:+conn.getResponseCode());
System.out.println(“响应消息:+conn.getResponseMessage());
连接断开();
}捕获(格式错误){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
}
Server.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,客户端和服务器密钥库的CN应为主机名。


如果有更好的解决方案,请提出建议。

下面的代码对我来说很好,在创建了两个客户端和服务器密钥库并将这两个证书都放入java信任库之后,我使用下面的代码进行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();
static final private String KEY\u STORE=“D:/sslcertificates/