Java KeyStore duplicate aliases

家住魔仙堡 提交于 2019-12-11 09:54:46

问题


I have a Java KeyStore with couple of entries sharing the same alias (duplicates). When I do a getEntry(...) or getCertificate(...) or getKey(...), I always get the first entry in all the cases. How do I always get the ones that I want?

I have tried exporting the first entry to an external file (using keytool), and then deleting the first entry from the original KeyStore, and then importing back the exported entry with a different alias. This would work if the entry is a Trusted Certificate. But it wouldn't work if it is a PrivateKeyEntry or a SecretKeyEntry.

Is there any feasible solution/fix to handle this scenario?


回答1:


There is one way of fixing the duplicate aliases. Since there is no direct way of fixing this issue, we can fix the duplicate aliases manually. You can run this code below to fix the duplicate aliases occurrences, (it is a one time thing).

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!!");
}

What this basically does is group all the entries that have common aliases, and moves/creates a new entry with a new alias (incremental counter appended to the existing alias) and deletes all the original entries.

You can see the new aliases in your console.

P.S: It is advised to have your original KeyStore backed-up.




回答2:


Instead of using KeyStore.deleteEntry (which causes problems for private keys), use KeyStore.setCertificateEntry(Alias, Certificate).



来源:https://stackoverflow.com/questions/36292718/java-keystore-duplicate-aliases

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!