仍然收到致命警报:bad_certificate,

时间:2018-05-21 13:22:59

标签: java spring ssl pem jks

我将密钥和证书(合并)合并到一个cert.pem文件中, 我得到了, “exception”:“javax.net.ssl.SSLHandshakeException”, “message”:“收到致命警报:bad_certificate”, pem file is right, but i think problem is how i generating jks keystore file.

.pem证书格式

  

BEGIN CERTIFICATE

     

...

     

END CERTIFICATE

     

BEGIN CERTIFICATE

     

...

     

END CERTIFICATE

     

BEGIN RSA PRIVATE KEY

     

...

     

END RSA PRIVATE KEY ###`

将它与keytool comand comand结合使用

keytool -import -trustcacerts -alias yourdomain -file combined.pem -keystore yourkeystore.jks

java代码是

public class HttpsTrustManager implements X509TrustManager {
    @Override
    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
        // TODO Auto-generated method stub

    }

    @Override
    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
        // TODO Auto-generated method stub

    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[]{};
    }
}

请求是

FileInputStream instream = new FileInputStream(
      new File(this.resourcePath()+"/path_to.jks")
  );
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(instream, "password".toCharArray());

    SSLContext sslContext = SSLContexts.custom()
            .loadKeyMaterial(keyStore, "password".toCharArray()) // use null as second param if you don't have a separate key password
            .build();

    sslContext.init(null,new X509TrustManager[]{new HttpsTrustManager()}, new SecureRandom());


    HttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build();
    HttpResponse response = httpClient.execute(
            new HttpPost("https://url")
    );
    HttpEntity entity = response.getEntity();

    System.out.println("----------------------------------------");
    System.out.println(response.getStatusLine());
    EntityUtils.consume(entity);

1 个答案:

答案 0 :(得分:0)

当您使用Apache SSLContexts.custom().loadKeyMaterial().build()时,它会使用指定的密钥库和默认的trustmanager初始化构建的上下文。然后,您使用 keymanager和指定的trustmanager将sslContext.init()调用重新 - 初始化它;这会忽略并丢弃先前的初始化。因此,您的上下文没有密钥管理器,也无法进行客户端身份验证。

你需要保持一致。使用Apache并给予(相同)构建器 loadKeyMaterial loadTrustMaterial对应于您想要的内容 - 特别是httpclient 4.5.4添加org.apache.http.conn.ssl.TrustAllStrategy实现"高兴地让所有小偷和骗子看到并改变我所谓的安全数据"。或者,使用JSSE直接创建SSLContext .getInstance().init()(一次!),使用零安全信任管理器和从密钥库创建的密钥管理器(以及显式{{1}如果你喜欢,但如果你省略它默认)。

但是,这可能不起作用,因为只有当SecureRandom是与您导入的证书链匹配的预先存在的PrivateKeyEntry时,您显示的keytool命令才是正确的。使用yourdomain确保它是PrivateKeyEntry而不是TrustedCertEntry。如果没有,并且如果您需要使用PEM文件中的私钥(而不是密钥库中已有的私钥),则需要首先使用OpenSSL将密钥证书链转换为PKCS12,然后依赖于您的Java 可能使用keytool -list -alias yourdomain将PKCS12转换为JKS。在几个堆栈上有几十个Q(和As)。