Java KeyStore 重复别名

标签 java keystore keytool

我有一个 Java KeyStore,其中有几个共享相同别名(重复)的条目。当我执行 getEntry(...)getCertificate(...)getKey(...) 时,我总是得到所有情况下的第一个条目。我怎样才能总是得到我想要的?

我尝试将第一个条目导出到外部文件(使用keytool),然后从原始 keystore 中删除第一个条目,然后使用不同的别名导入回导出的条目。如果该条目是受信任的证书,则这将起作用。但如果是 PrivateKeyEntry 或 SecretKeyEntry 则不起作用。

有没有可行的解决方案/修复来处理这种情况?

最佳答案

有一种方法可以修复重复的别名。由于没有直接的方法来解决这个问题,我们可以手动修复重复的别名。您可以运行下面的代码来修复重复的别名出现(这是一次性的事情)。

public static void removeDuplicateAliases() throws NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, KeyStoreException,
        UnrecoverableEntryException
{
    final String KEYSTORE_TYPE = "KEYSTORE_TYPE";
    final String KEYSTORE_PATH = "KEYSTORE_PATH";
    final char[] KEYSTORE_PASSWORD = "KEYSTORE_PASSWORD".toCharArray();

    KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);
    ks.load(new FileInputStream(new File(KEYSTORE_PATH)), KEYSTORE_PASSWORD);

    Enumeration<String> aliases = ks.aliases();

    Map<String, List<KeyStore.Entry>> keyStoreEntriesMap = new LinkedHashMap<String, List<KeyStore.Entry>>();

    while (aliases.hasMoreElements())
    {
        String alias = aliases.nextElement();

        KeyStore.Entry entry = null;

        try
        {
            entry = ks.getEntry(alias, new KeyStore.PasswordProtection(KEYSTORE_PASSWORD));
        }
        catch (UnsupportedOperationException e)
        {
            entry = ks.getEntry(alias, null);
        }

        if (!keyStoreEntriesMap.containsKey(alias))
        {
            List<KeyStore.Entry> aliasEntry = new ArrayList<KeyStore.Entry>();
            aliasEntry.add(entry);

            keyStoreEntriesMap.put(alias, aliasEntry);
        }
        else
        {
            keyStoreEntriesMap.get(alias).add(entry);
        }
    }

    for (Map.Entry<String, List<KeyStore.Entry>> entry : keyStoreEntriesMap.entrySet())
    {
        if (entry.getValue().size() > 1)
        {
            System.out.println("Multiple entries found under same alias - \'" + entry.getKey() + "\'");

            int counter = 1;
            for (KeyStore.Entry each : entry.getValue())
            {
                ks.deleteEntry(entry.getKey());

                String newAlias = entry.getKey() + "-" + counter;

                if (each instanceof TrustedCertificateEntry)
                    ks.setEntry(newAlias, each, null);
                else
                    ks.setEntry(newAlias, each, new KeyStore.PasswordProtection(PASSWORD));

                System.out.println("\t(" + counter + " of " + entry.getValue().size() + ") Entry moved to new alias \'" + newAlias + "\'");

                counter++;
            }

            System.out.println();
        }
    }

    ks.store(new FileOutputStream(new File(KEYSTORE_PATH)), PASSWORD);

    System.out.println("Done!!");
}

这基本上所做的是将具有公共(public)别名的所有条目分组,并移动/创建具有新别名的新条目(增量计数器附加到现有别名)并删除所有原始条目。

您可以在控制台中看到新的别名。

P.S:建议您备份原始KeyStore。

关于Java KeyStore 重复别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36292718/

相关文章:

java - TarsosDSP 拍手检测

java - 如何重定向到部署在本地服务器上的应用程序中的 spring Controller 方法?

java - 您应该使用 equals 方法还是比较 Esper 中 EventType 的事件类型 ID?

java - JKS key 存储格式规范

java - exec() 在 Debian 7 上不起作用

java - 如何从 Java 生成、签署和导入 SSL 证书

ssl - 如何使用 keytool 使用 SHA2 签名算法生成受信任的自签名证书?

java - 是否有用于更好线性回归的 Java 库? (例如,迭代重新加权最小二乘法)

java - Kurento - 配置 Java 应用程序以使用 https - keystore 错误

java - NetBeans 中出现认证错误,即使 ".CER"文件已添加到 KeyStore