Java: неверный формат хранилища ключей при генерации с помощью кода

StackOverflow https://stackoverflow.com/questions/1816810

Вопрос

Это было задано несколько раз, но ни один из них не содержит кодовых тестов Здесь я приведу пример проблемы:

<Ол>
  • программная генерация хранилища ключей (работает)
  • создание сертификата в этом магазине (работает)
  • сохранение хранилища ключей на диск (работает)
  • перечисление хранилища ключей с помощью keytool (работает)
  • программная загрузка хранилища ключей (ошибка IOException: InvalidKeystoreFormat)
  • Чего я не понимаю, так это того, что при сохранении и загрузке я использую KeyStore.getInstance (" JKS ") , но это не удается. Любые предложения приветствуются!

    Время выполнения:

    Creating private keystore at 'private.keystore'.
    Created keystore, now created signer cert
    Created signer cert, saving cert
    Reloading keystore:
    Failed to load the keystore after creation: Invalid keystore format
    

    Источник тестового примера:

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.security.InvalidKeyException;
    import java.security.KeyStore;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;
    import java.security.PrivateKey;
    import java.security.SignatureException;
    import java.security.cert.Certificate;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    import sun.security.x509.X500Name;
    
    public class KeystoreCreator
    {
     private String fPrivateKeyStore;
     private String fPrivateKeyStorePassword;
     private String fPrivateKeyStoreKeyPassword;
     private String fPublicKeyCipherPassword;
     private String fPrivateKeyAlias;
    
     /**
      * @param args
      * @throws Exception 
      */
     public static void main(String[] args) throws Exception
     {
      KeystoreCreator creator = new KeystoreCreator();
    
      creator.setPrivateKeyStore("private.keystore");
      creator.setPrivateKeyStorePassword("beer123");
    
      creator.setPrivateKeyAlias("myalias");
      creator.setPrivateKeyStoreKeyPassword("beer123");
      creator.setPublicKeyCipherPassword("beer123");
    
      creator.initKeyStores();
     }
    
     public KeystoreCreator()
     {  
     }
    
     public void setPrivateKeyStore(String name)
     {
      fPrivateKeyStore=name;
     }
     public void setPrivateKeyStorePassword(String pass)
     {
      fPrivateKeyStorePassword=pass;
     }
     public void setPrivateKeyStoreKeyPassword(String pass)
     {
      fPrivateKeyStoreKeyPassword=pass;
     }
     public void setPublicKeyCipherPassword(String pass)
     {
      fPublicKeyCipherPassword=pass;
     }
     public void setPrivateKeyAlias(String alias)
     {
      fPrivateKeyAlias=alias;
     }
    
        public void initKeyStores() throws Exception
        {
            OutputStream out = null;
            File f=new File(fPrivateKeyStore);
            if (f.exists())
            {
             f.delete();
             if (f.exists())
             {
              throw new IOException("Want to remove the keystore but can't, still reported as present after removal");
             }
            }
            try
            {
             System.out.println("Creating private keystore at '" + fPrivateKeyStore + "'.");
             out = new FileOutputStream(fPrivateKeyStore);
             KeyStore privateKeyStore = KeyStore.getInstance("JKS");
             privateKeyStore.load(null, fPrivateKeyStorePassword.toCharArray());
    
             System.out.println("Created keystore, now created signer cert");
             X500Name x500name=getCA();
             Certificate cert = createCertificate(fPrivateKeyAlias, fPrivateKeyStoreKeyPassword, x500name, privateKeyStore);
    
             System.out.println("Created signer cert, saving cert");
             privateKeyStore.store(out, fPublicKeyCipherPassword.toCharArray());
             out.flush();
             out.close();
             //try to load it.
             KeyStore reloadedKeyStore = KeyStore.getInstance("JKS");
             try
             {
              InputStream reloadedIs=getClass().getClassLoader().getResourceAsStream(fPrivateKeyStore);
              if (reloadedIs!=null)
              {
               System.out.println("Reloading keystore:");
               reloadedKeyStore.load(reloadedIs, fPrivateKeyStorePassword.toCharArray());
              }
             }
             catch (Exception e)
             {
              System.err.println("Failed to load the keystore after creation: "+e.getLocalizedMessage());
             }
            }
            catch (Exception e)
            {
             System.err.println("Failed to save the keystore: "+e.getLocalizedMessage());
            }
        }
    
        private X500Name getCA() throws IOException
        {
         return new sun.security.x509.X500Name("a","b", "c","d","e", "GB");
        }
    
        public Certificate createCertificate( String alias, String keyPassword,
                sun.security.x509.X500Name x500Name, KeyStore keyStore ) throws NoSuchAlgorithmException,
                InvalidKeyException, CertificateException, SignatureException, NoSuchProviderException,
                KeyStoreException {     
            sun.security.x509.CertAndKeyGen keypair = new sun.security.x509.CertAndKeyGen( "RSA", "MD5WithRSA" );
            keypair.generate( 1024 );
            PrivateKey privKey = keypair.getPrivateKey();
            X509Certificate[] chain = new X509Certificate[1];
            chain[0] = keypair.getSelfCertificate( x500Name, 7000 * 24 * 60 * 60 );
            keyStore.setKeyEntry( alias, privKey, keyPassword.toCharArray(), chain );
    
            Certificate cert = keyStore.getCertificate( alias );
            return cert;
        }
    }
    
    Это было полезно?

    Решение

    1) Вы создаете хранилище закрытых ключей в текущем рабочем каталоге, записывая в файл : new FileOutputStream (fPrivateKeyStore);

    2) Позже вы читаете из пути к классу , используя getClass (). getClassLoader (). getResourceAsStream (fPrivateKeyStore);

    Я думаю, что вы читаете не те файлы. И уже есть другой с именем private.keystore из предыдущих тестов. Для проверки вы можете распечатать абсолютный путь к файлу обоих файлов, например, новый файл (fPrivateKeyStore) .getAbsolutePath () и сравните его с getClass (). getClassLoader (). getResource (fPrivateKeyStore) .toFileURL ();

    Другие советы

    Я могу что-то упустить, но почему бы просто не перезагрузить хранилище закрытых ключей, используя FileInputStream ?

    InputStream reloadedIs = new FileInputStream(fPrivateKeyStore);
    

    (я не уверен, что это решит проблему, я только заметил это при сканировании вашего кода)

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top