为什么 Keytool 在添加过期证书时不会警告您

问题描述

我试图使用 SOAP 向主机服务器发送请求,它需要一个证书,因为 cxf 需要一个证书。

我使用此命令将证书导出到 cacerts 中的 JAVA_HOME 文件

keytool -import -trustcacerts -alias fooAlias -file foo -keystore cacerts

但是在尝试再次发送请求后,我得到了这个异常:

 pkix path building Failed: sun.security.provider.certpath.suncertpathbuilderexception:
 unable to find valid certification path to requested target

当然,我去找了一个解决方案,结果是将证书添加cacerts 文件我已经这样做了!!,所以它造成了一种混乱为什么会发生这种情况。

然后经过 2 天的尝试并失去所有希望后,我偶然打开了证书,发现它在 3 个月前已过期。

我联系了团队并请求了一个新的有效请求,添加错误消失了,请求被发送了。

所以请有人告诉我为什么当我尝试添加过期的证书时 keytool 没有显示警告。

这样做是有道理的,因为错误是因为它已过期而被抛出。

为什么它甚至允许添加过期的证书。

解决方法

当您尝试添加证书时,Keytool 不会发出警告。您使用的命令将根或中间 CA 证书导入到现有的 Java 密钥库,它对您执行相同的操作。

由于该命令只要求提供证书实例,因此它从不检查有效性。有效性检查应该由证书的用户而不是提供者来完成。所以代码按预期工作。
您可以通过

检查证书的有效性
$ keytool -printcert -v -file [CERTIFICATE]

输出

Owner:
Issuer: CN=CPD Root CA,DC=cpd,DC=local<br>
Serial number: 39e8d1610002000000cb
<br>Valid from: Wed Feb 22 21:36:31 CET 2012 until: Thu Feb 21 21:36:31 CET 2013
Certificate fingerprints: <br>
         MD5:  82:46:8B:DB:BC:5C:64:21:84:BB:68:E3:4B:D4:35:70<br>
         SHA1: 35:52:CA:F2:11:66:1E:50:63:BC:53:A5:50:C1:F0:1E:62:81:BC:3F<br>
         Signature algorithm name: SHA1withRSA

为了更好地理解,您可以查看下面的代码。

  1. Keytool.java 有一个 main 方法,它接受所有参数 你正在通过。然后它解析它并将它传递给 doCommands 进一步处理。

    public static void main(String[] args) throws Exception {
        Main kt = new Main();
        kt.run(args,System.out);
    }
    
    private void run(String[] args,PrintStream out) throws Exception {
        try {
            parseArgs(args);
            if (command != null) {
                doCommands(out);
            }
    
  2. 然后它调用 KeyStoreUtil 来获取 CacertsKeystore。

    if (trustcacerts) {
         caks = KeyStoreUtil.getCacertsKeyStore();
    }
    
  3. 它从 KeystoreUtil 获取文件并调用 KeyStore 来获取实例。

    /**
     * Returns the keystore with the configured CA certificates.
    */
    public static KeyStore getCacertsKeyStore() throws Exception {
    File file = new File(getCacerts());
    if (!file.exists()) {
        return null;
    }
    return KeyStore.getInstance(file,(char[])null);
    

    }

  4. 在 KeyStore 中,它返回一个已加载的适当密钥库类型的密钥库对象。

    public static final KeyStore getInstance(File file,char[] password)
    throws KeyStoreException,IOException,NoSuchAlgorithmException,CertificateException {
    return getInstance(file,password,null,true);
    }