Java: неверный формат хранилища ключей при генерации с помощью кода
-
08-07-2019 - |
Вопрос
Это было задано несколько раз, но ни один из них не содержит кодовых тестов Здесь я приведу пример проблемы:
<Ол>Чего я не понимаю, так это того, что при сохранении и загрузке я использую 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);
(я не уверен, что это решит проблему, я только заметил это при сканировании вашего кода)