2016-03-29 4 views
1

私は同じエイリアス(重複)を共有するエントリのカップルを持つJava KeyStoreを持っています。 getEntry(...)またはgetCertificate(...)またはgetKey(...)を実行すると、すべてのケースで常に最初のエントリが取得されます。どのように私はいつも私が欲しいものを手に入れますか?Java KeyStore重複したエイリアス

最初のエントリを(keytoolを使用して)外部ファイルにエクスポートしてから、元のKeyStoreから最初のエントリを削除して、別のエイリアスでエクスポートしたエントリをインポートしてみました。これは、エントリが信頼できる証明書である場合に機能します。しかし、それがPrivateKeyEntryまたはSecretKeyEntryであれば動作しません。

このシナリオを処理するための実行可能な解決策はありますか?

答えて

1

重複するエイリアスを修正する1つの方法があります。この問題を直接修正する方法はないので、重複した別名を手動で修正することができます。以下のコードを実行すると、エイリアスの重複を修正できます(これは一度だけのことです)。これは基本的に何

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

は、共通の別名を持つグループのすべてのエントリで、移動/は(既存の別名に追加増分カウンタ)新しいエイリアスを持つ新しいエントリを作成し、すべての元のエントリを削除します。

コンソールに新しいエイリアスが表示されます。

P.S:オリジナルのKeyStoreをバックアップしておくことをお勧めします。

+0

マルチマップは、このコードを少し読みやすくします。 –

0

KeyStore.deleteEntry(プライベートキーに問題を引き起こす)を使用する代わりに、KeyStore.setCertificateEntry(別名、証明書)を使用します。