当前位置: 首页 > 知识库问答 >
问题:

收到致命警报:bad_证书

刘博雅
2023-03-14

我正在尝试设置SSL Socket连接(并且正在客户端上执行以下操作)

>

  • 我生成证书签名请求以获取签名的客户端证书

    现在我有一个私钥(在CSR期间使用)、一个签名的客户端证书和根证书(在带外获得)。

    我将私钥和已签名的客户端证书添加到证书链,并将其添加到密钥管理器。并将根证书发送给信任管理器。但是我得到了一个错误的证书。

    我很确定我使用的是正确的证书。我是否也应该将已签名的客户端证书添加到信任管理器?试过了,还是不走运。

    //I add the private key and the client cert to KeyStore ks
    FileInputStream certificateStream = new FileInputStream(clientCertFile);
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    java.security.cert.Certificate[] chain = {};
    chain = certificateFactory.generateCertificates(certificateStream).toArray(chain);
    certificateStream.close();
    String privateKeyEntryPassword = "123";
    ks.setEntry("abc", new KeyStore.PrivateKeyEntry(privateKey, chain),
            new KeyStore.PasswordProtection(privateKeyEntryPassword.toCharArray()));
    
    //Add the root certificate to keystore jks
    FileInputStream is = new FileInputStream(new File(filename));
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    java.security.cert.X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
    System.out.println("Certificate Information: ");
    System.out.println(cert.getSubjectDN().toString());
    jks.setCertificateEntry(cert.getSubjectDN().toString(), cert);
    
    //Initialize the keymanager and trustmanager and add them to the SSL context
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(ks, "123".toCharArray());
    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
    tmf.init(jks);
    

    我需要在这里创建某种证书链吗<我有一个带有这些组件的p12,在使用非常类似的代码后,将私钥添加到keymanager,并将根证书从p12添加到信任管理器,我可以使其工作。但是现在我需要让它在没有p12的情况下工作。

    编辑:已请求堆栈跟踪。希望这足够了。(注意:我屏蔽了文件名)

    Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1720)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
    at client.abc2.openSocketConnection(abc2.java:33)
    at client.abc1.runClient(abc1.java:63)
    at screens.app.abc.validateLogin(abc.java:197)
    ... 32 more
    
  • 共有3个答案

    云德辉
    2023-03-14

    如果服务器证书已签名且有效,则只需像往常一样打开连接:

    import java.net.*;
    import java.io.*;
    
    public class URLConnectionReader {
        public static void main(String[] args) throws Exception {
            URL google = new URL("https://www.google.com/");
            URLConnection yc = google.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                                        yc.getInputStream()));
            String inputLine;
            while ((inputLine = in.readLine()) != null) 
                System.out.println(inputLine);
            in.close();
        }
    }
    

    请注意,URL具有HTTPS模式以指示SSL的使用。

    如果服务器的证书已签名,但您使用的IP地址/域名与证书中的不同,则可以通过以下方式绕过主机名验证:

    HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String urlHostName,SSLSession session) {
            return true;
        }
    };
    
    HttpsURLConnection.setDefaultHostnameVerifier(hv);
    

    如果证书没有签名,则需要将其添加到JVM使用的密钥库(有用的命令)。

    葛昕
    2023-03-14

    当我删除这两行时,出现了这个错误。如果您知道您的密钥库具有正确的证书,请确保您的代码正在查看正确的密钥库。

    System.setProperty("javax.net.ssl.keyStore", <keystorePath>));
    System.setProperty("javax.net.ssl.keyStorePassword",<keystorePassword>));
    

    我还需要这个VM参数:-Djavax.net.ssl.trustStore=/app/certs/keystore.jk请参阅此处了解更多详细信息:https://stackoverflow.com/a/34311797/1308453

    娄振
    2023-03-14

    您还需要将根证书添加到密钥库。

     类似资料:
    • 问题内容: 我正在尝试使用 liferay中的* javapns 库将推送通知发送到我的设备。这是代码: * 调用pushNotification时出现此错误: 我已经用谷歌搜索了,但是找不到任何解决方案。 有谁知道如何解决这个问题? 问题答案: 当您要连接的服务器没有来自授权CA的有效证书时,通常会引发该异常。 简而言之,您尝试连接的服务器很可能使用自签名证书,因此您必须在Java代码中容纳该证

    • 问题内容: 我正在尝试建立SSL套接字连接(并在客户端上执行以下操作) 我生成了证书签名请求以获取签名的客户证书 现在,我有一个私钥(在CSR中使用),一个签名的客户端证书和根证书(带外获得)。 我将私钥和签名的客户端证书添加到证书链中,并将其添加到密钥管理器中。和根证书到信任管理器。但是我收到了错误的证书错误。 我很确定自己使用的证书正确。是否也应该将签名的客户端证书添加到信任管理器?试了一下,

    • 问题内容: 有人遇到过此错误吗?我是SSL新手,我缺少的ClientHello明显有问题吗?没有ServerHello响应时抛出该异常。任何建议表示赞赏。 { http://xml.apache.org/axis/ } stackTrace: … 问题答案: 在Java 1.8上,默认TLS协议为v1.2。在Java 1.6和1.7上,默认的TLS1.0已过时。我在Java 1.8上收到此错误,因

    • 问题内容: 我从两天后尝试了许多选项后发布了这个问题。以下是我尝试的选项。 禁用SSL证书验证 通过从浏览器下载crt并转换为.jks并导入密钥库。 我仍然遇到这个问题,非常感谢您的任何帮助。 问题答案: 问题解决了。!!!以下是解决方案。 对于Java 6:将下面的jar添加到{JAVA_HOME} / jre / lib / ext中。1. bcprov-ext- jdk15on-154.ja

    • 我在使用Java 1.7.0_67的linux服务器上使用Tomcat 7.065和APR 1.1.33。 多年来,我的应用程序一直通过SSL愉快地连接到第三方站点。第三方颁发了一个新证书。第三部分站点是:https://its.changehealthcare.com/ 我下载了。cer文件并导入了一个keytool: 当我做一个keytools列表时,我得到: 但是我继续得到一个ssl握手错误

    • 我在Java 8上运行以下代码, 获得例外, ioException 在发送 http 请求时发生:javax.net.ssl.SSLHandshake异常:收到致命警报:handshake_failure。 我能够通过卷曲连接到, 有人能告诉我我的java代码有什么问题吗? 依赖关系如下,