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

当有多个证书具有相同的受托人时,如何从信任存储库中选择所需的信任证书X500原则

屠振濂
2023-03-14

我有一个服务器根证书即将使用SHA1过期,并使用SH256获得了一个新的服务器根证书,使用寿命更长。我们希望在我们的客户机信任存储中包括这两个方面,以便在prod环境切换证书时能够顺利过渡。

通过javax加载信任存储,我们在代码中提供了信任管理器。网ssl。TrustManagerFactory,然后我们在运行客户端应用程序时看到一个错误:

Caused by: java.security.SignatureException: Signature length not correct: got 256 but was expecting 128
    at sun.security.rsa.RSASignature.engineVerify(RSASignature.java:189)
    at java.security.Signature$Delegate.engineVerify(Signature.java:1222)
    at java.security.Signature.verify(Signature.java:655)
    at sun.security.x509.X509CertImpl.verify(X509CertImpl.java:444)
    at sun.security.x509.X509CertImpl.verify(X509CertImpl.java:392)
    at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:213)

这两个受信任证书的颁发者相同,但过期日期和签名算法不同。

我发现根本原因是太阳。安全验证器。SimpleValidator仅在同一颁发者有多个证书的情况下选择第一个受信任的证书

源代码jdk的SimpleValidator显示了原因,如果同一个颁发者有多个信任证书,那么将始终使用第一个:

        // check if we can append a trusted cert
        X509Certificate cert = chain[chain.length - 1];
        X500Principal subject = cert.getSubjectX500Principal();
        X500Principal issuer = cert.getIssuerX500Principal();
        List<X509Certificate> list = trustedX500Principals.get(issuer);
        if (list != null) {
            X509Certificate trustedCert = list.iterator().next();
            c.add(trustedCert);
            return c.toArray(CHAIN0);
        }

我希望有一种方法可以基于同一颁发者的所有受信任证书来验证服务器证书。

或者根据发行人和签名算法选择正确的信任证书。

任何帮助都将不胜感激。

共有2个答案

公良俊楚
2023-03-14

类似于下面的内容——创建ssl上下文时

private TrustManager[] wrapLoggingTrustDelegate(TrustManager[] trustManagers) {
    if (trustManagers == null || trustManagers.length == 0) {
        return trustManagers;
    }
    TrustManager[] result = new TrustManager[trustManagers.length];
    for (int i = 0; i < trustManagers.length; i++) {
        result[i] = (trustManagers[i] == null || !(trustManagers[i] instanceof X509TrustManager)) ? trustManagers[i] : new SigNameMatchingX509TrustManager(new LoggingDelegateX509TrustManager((X509TrustManager)trustManagers[i]), trustManagerKeyStore);
    }
    return result;
}

private SSLContext getSslContext() {
    SSLContext sc;

    try {
        sc = SSLContext.getInstance(sslContextType);
        sc.init(wrapLoggingKeyDelegate(keyManagerFactory.getKeyManagers()), wrapLoggingTrustDelegate(trustManagerFactory.getTrustManagers()), null);
    } catch (Exception e) {
        log.error("Error configuring SSL Context.", e);
        throw new IllegalStateException("Error configuring the SSL Context", e);
    }

    return sc;
}
祁俊喆
2023-03-14

我敢打赌,你连接的服务器只会用叶子证书响应。超级简单的解决方案是请求服务器使用完整链(叶中间根CA)进行响应,这样java就可以直接从提供的证书中获取签名名/算法。

如果不可能,那么在将服务器证书链传递到验证器时,需要根据颁发者和签名算法名称将所需的信任证书附加到链中。参考:https://github.com/frohoff/jdk8u-jdk/blob/da0da73ab82ed714dc5be94acd2f0d00fbdfe2e9/src/share/classes/sun/security/validator/SimpleValidator.java#L378

 类似资料:
  • 我已经看到了一些使用X509TrustManager实现TrustManager的示例,尽管显然Java7不支持这些约定,X509TrustManager本身也被弃用。 感谢您的建议和任何在Java7上工作的代码示例。

  • 在证书链验证期间,我需要将自定义的自签名根证书标记为受信任的,总的来说,我希望尽可能依赖系统API。 我创建了一个临时内存存储。 然后我将自定义根证书放入存储中。 CertGet证书链MSDN留档表示 HadAdditional存储任何附加存储的句柄,以搜索支持证书和证书信任列表(CTL)。 据我所知,如果我用根证书创建一个CTL并将其放置到存储中,CertGet证书链将信任它。因此,我在分配的缓

  • 当我尝试安装扩展时,出现以下错误: 我已经知道问题是我们的内部网络结构,它用我们自己的SSL证书包装每个SSL证书,而不是每个应用程序都信任我们的证书。 是否可以在Visual Studio代码中设置属性Trust all SSL证书? 谢啦

  • 目前,我在我的用户目录中的中有以下条目。 这将设置与git服务器交互时使用的证书(我公司的git服务器需要)。 但现在我无法克隆其他存储库(例如GitHub上的公共存储库),因为客户端总是使用配置好的证书,而该证书会被其他服务器拒绝。 我如何规避此认证问题?我可以将Git配置为使用Windows证书存储进行身份验证吗?

  • 我已经在我的spring boot应用程序中启用了ssl,并且任何时候我想使用像GooglePis或facebook这样的Rest服务,我都必须在TrustStore中添加证书。 我使用openssl获取证书: openssl s_client-connect googleapis.com:443 并将其导入truststore: keytool.exe-import-noprompt-trust

  • 我遇到了一个奇怪的问题——供应商使用TLS SSLv3,同时使用自签名客户端和服务器证书。Java1.5和Java1.6没有这个问题——只需将客户端证书和私钥导入密钥库,将服务器公共证书导入信任库。一切都很好。然而,在Java7中,服务器证书无法被信任,即使使用的是同一个信任库。我尝试过使用Java7 (1.7.03, 04和05、x86和x64版本)的视窗和红帽,但没有成功。 我从头开始重新创建