Java KeyStore 重复别名
Java KeyStore duplicate aliases
我有一个 Java KeyStore,其中有几个条目共享相同的别名(重复项)。当我执行 getEntry(...)
或 getCertificate(...)
或 getKey(...)
时,我总是在所有情况下获得第一个条目。我怎样才能总能得到我想要的?
我试过将第一个条目导出到外部文件(使用 keytool
),然后从原始 KeyStore 中删除第一个条目,然后用不同的别名导回导出的条目。如果条目是受信任的证书,这将起作用。但如果它是 PrivateKeyEntry 或 SecretKeyEntry 则不起作用。
是否有任何可行的方法solution/fix来处理这种情况?
有一种方法可以修复重复的别名。由于没有直接的方法来解决这个问题,我们可以手动修复重复的别名。您可以 运行 下面的这段代码来修复重复的别名出现(这是一次性的事情)。
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!!");
}
这基本上是将所有具有共同别名的条目分组,moves/creates 一个具有新别名的新条目(附加到现有别名的增量计数器)并删除所有原始条目。
您可以在控制台中看到新的别名。
P.S: 建议备份好你原来的KeyStore
不要使用 KeyStore.deleteEntry(这会导致私钥出现问题),而是使用 KeyStore.setCertificateEntry(别名,证书)。
我有一个 Java KeyStore,其中有几个条目共享相同的别名(重复项)。当我执行 getEntry(...)
或 getCertificate(...)
或 getKey(...)
时,我总是在所有情况下获得第一个条目。我怎样才能总能得到我想要的?
我试过将第一个条目导出到外部文件(使用 keytool
),然后从原始 KeyStore 中删除第一个条目,然后用不同的别名导回导出的条目。如果条目是受信任的证书,这将起作用。但如果它是 PrivateKeyEntry 或 SecretKeyEntry 则不起作用。
是否有任何可行的方法solution/fix来处理这种情况?
有一种方法可以修复重复的别名。由于没有直接的方法来解决这个问题,我们可以手动修复重复的别名。您可以 运行 下面的这段代码来修复重复的别名出现(这是一次性的事情)。
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!!");
}
这基本上是将所有具有共同别名的条目分组,moves/creates 一个具有新别名的新条目(附加到现有别名的增量计数器)并删除所有原始条目。
您可以在控制台中看到新的别名。
P.S: 建议备份好你原来的KeyStore
不要使用 KeyStore.deleteEntry(这会导致私钥出现问题),而是使用 KeyStore.setCertificateEntry(别名,证书)。