Pregunta

Esto se ha pedido un par de veces, pero ninguno proporciona casos de prueba codificados. Aquí les doy un ejemplo del problema:

  1. generación programática de un Keystore (funciona)
  2. creación de certificado dentro de esa tienda (funciona)
  3. guardar el almacén de claves en el disco (funciona)
  4. listado de almacén de claves con keytool (funciona)
  5. cargar el almacén de claves mediante programación (falla con IOException: InvalidKeystoreFormat)

Lo que no obtengo es que, tanto en guardar como en cargar, uso KeyStore.getInstance (" JKS ") , pero falla. Cualquier sugerencia bienvenida!

Salida en tiempo de ejecución:

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

Fuente del caso de prueba:

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;
    }
}
¿Fue útil?

Solución

1) Usted crea el almacén de claves privadas en el directorio de trabajo actual, escribiendo en un archivo : new FileOutputStream (fPrivateKeyStore);

2) Más tarde, lee desde la ruta de clase utilizando getClass().getClassLoader().getResourceAsStream(fPrivateKeyStore);

Creo que estás leyendo los archivos incorrectos. Y ya hay otro con el nombre private.keystore de pruebas anteriores. Para verificar, es posible que desee imprimir la ruta absoluta del archivo de ambos archivos, p. new File (fPrivateKeyStore) .getAbsolutePath () y compárelo con getClass().getClassLoader().getResource(fPrivateKeyStore).toFileURL();

Otros consejos

Puede que me falte algo, pero ¿por qué no volver a cargar el almacén de claves privadas usando FileInputStream ?

InputStream reloadedIs = new FileInputStream(fPrivateKeyStore);

(No estoy seguro de que esto solucione el problema, solo lo noté mientras escaneaba su código)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top