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

如何信任我自己签名的证书

梁建德
2023-03-14

我想通过SSL连接到我的服务器。因此,我使用以下命令在服务器上生成证书:

openssl genrsa -out server.pem 2048
openssl req -new -x509 -nodes -sha1 -days 3650 -key server.pem > server.cert

如果我使用如下所示的TrustManager信任客户端上的所有证书,则连接可以正常工作:

X509TrustManager tm = new X509TrustManager() {

    @Override
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
    }

    @Override
    public void checkClientTrusted(
            X509Certificate[] certs, String authType) {
    }

    @Override
    public void checkServerTrusted(
            X509Certificate[] certs, String authType) {
    }
};

但我当然不想相信所有的证书,而只相信我的证书。我尝试了以下几个命令来导入证书:

keytool -import -alias ca -file server.cert -keystore cacerts
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

我要怎么做才能让它正常工作?有人能解释一下对一个不是很熟悉cryto领域的人所必需的步骤吗?

编辑:正如Donal Fellows所建议的那样,我尝试了自定义X509TrustManager的方法,它起作用了。但这样安全吗?如果我在“getAcceptedissuers”方法中返回“null”,它也起作用,我不太清楚为什么:

X509TrustManager tm = new X509TrustManager() {

    @Override
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {

        X509Certificate[] trustedCerts = new X509Certificate[1];
        try{
            InputStream inStream = new FileInputStream("server.cert");
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
            inStream.close();
            trustedCerts[0] = cert;
        }catch(Exception e){
            e.printStackTrace();
        }

        return trustedCerts;
    }

    @Override
    public void checkClientTrusted(
            X509Certificate[] certs, String authType) {
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain,
            String authType) throws CertificateException {

        boolean match = false;
        try{


            InputStream inStream = new FileInputStream("server.cert");
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
            inStream.close();

            for(X509Certificate c : chain){
                if(c.equals(cert)){
                    match = true;
                }
            }
        }catch(Exception e){
            throw new CertificateException();
        }

        if(!match)
            throw new CertificateException();

    }

};

共有1个答案

储阳曦
2023-03-14

如果您真的要锁定内容,可以通过安装自定义X509TrustManager来实现,该自定义X509TrustManager测试所使用的证书是否与您认为它应该是的证书(您可以肯定地知道,您已经生成了它)。这实际上是相当安全的,但不允许任何操作灵活性;如果服务器受到威胁,您必须重新生成密钥,那么所有客户端也将需要更新。

因为这真的很烦人(而且不能扩展到像WWW这样的东西),所以使用trust root更正常。信任根是一个自签名的CA证书,通常具有较长的寿命,用于对部署到服务器的工作证书进行签名。(您可以使用CA证书本身,但通常最好保持脱机状态,可能是在防火保险箱中的可移动介质上。)然后您将CA证书放入客户机上的信任存储库(即,一个只保存证书的密钥存储库)中,并告诉Java使用它。

实际上,你就快到了。您可能只需要告诉Java使用cacerts信任库。您可以通过设置正确的system属性来做到这一点。

// Be careful on Windows; this property (unusually!) uses “/” instead of “\”
System.setProperty("javax.net.ssl.trustStore", "/path/to/cacerts");
 类似资料:
  • 我已经为我的服务器生成了自我签名的证书。然后用设置->安全->安装添加到Android中。 据我所知,在我将证书添加到受信任的列表中之后,它应该可以很好地工作。我是不是漏掉了什么?其思路是通过Android系统添加证书,无需修改应用程序代码。 顺便说一句,我使用进行网络连接。也许我应该启用连接?

  • 当我们过渡到使用已购买的.dev域进行本地开发时,我正在使用以下代码生成证书: 证书在Mac OSX上运行良好,添加到钥匙链访问后,但在ubuntu上,我使用任何浏览器都遇到了问题。

  • 我正试图将我的计算机配置为信任用于测试网站的自签名证书。然而,我在Firefox上遇到了一些问题。Chrome和IE都没问题。 我做了以下几点。 使用OpenSSL创建2048位pem rsa密钥和crt 从密钥和crt文件创建pfx文件 使用MMC将pfx导入到服务器上的个人证书存储中 将IIS配置为使用站点的证书 在客户端PC上 null 我还尝试将证书直接添加到Firefox的权限列表中。它

  • MarkFisher.Local使用了无效的安全证书。证书不是来自受信任的源。错误代码:MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY 我已按此答案中的建议将设置为。此外,转到首选项>隐私与安全>查看证书,我可以看到我的证书在“授权”选项卡中,并且我已经在“编辑信任”对话框中选中了“此证书可以标识网站”。这个原来没有检查 然而,Firefox拒绝接受该证

  • 如果URL使用自签名证书,则在以下情况下失败 我知道我可以将传递给参数,如下所示: 但是,我想做的是将请求指向磁盘上的公钥副本,并告诉它信任该证书。

  • 问题内容: 我试图使用(java)密钥工具创建一个自签名证书,但是当我尝试使用它时,出现以下异常(有关完整异常,请参见底部)。 我知道我可以使用以下代码绕过此代码: (资源) 但是我对此解决方案不感兴趣,因为我认为这会造成安全漏洞。(如果我错了,请纠正我)。 谁能指出我正确的方向?我目前正在本地进行测试,因此很容易进行更改。我可以访问服务器代码,客户端代码和.keystore文件。 更新资料 我试