HitchHiker
HitchHiker

Reputation: 847

Create a keystore file (.jks) and a self signed certificate (.cer/.crt) in Java

I want to create a keystore file (.jks) and a self signed certificate (.cer/.crt) in Java. I am trying this with :

Generate the keystore :

protected void getKeyStore(X509Certificate certificate)
{
    File newSnKeyStoreFile = new File("Mypath..\\keyStore.jks");

    try {

        KeyStore keyStore = KeyStore.getInstance("JKS");
        keyStore.load(null, null);

        if(!certificate.toString().isEmpty())
        {
            keyStore.store(new FileOutputStream(newSnKeyStoreFile), "password".toCharArray());
            if (keyStore.getCertificateAlias(certificate) == null) {
                keyStore.setCertificateEntry("cert"+ count++, certificate);
            }
        }
        keyStore.store(new FileOutputStream(newSnKeyStoreFile), KEYSTORE_PASSWORD.toCharArray());

        // Write to .jks file
        BufferedWriter out = null;
        try {
            out = new BufferedWriter(new FileWriter(newSnKeyStoreFile));
            out.write(keyStore.toString());
        } catch ( Exception e ) {
            e.printStackTrace();
        } finally {
            if ( out != null ) out.close();
        }
    }catch(Exception ke){
        System.out.print("Error occurred while setting up keyStore: " + ke.getMessage());
    }
}

I generate the certificate :

protected X509Certificate genCertificate()
{
    try {
        //Generate self signed certificate
        CertAndKeyGen gen = new CertAndKeyGen("RSA", "SHA1WithRSA")
        gen.generate(1024);
        X509Certificate cert = gen.getSelfCertificate(new X500Name("CN=ROOT"), (long) 365 * 24 * 3600);

        File certFile = new File("Mypath..\\Cert.cer");
        // Write to .cer file
        BufferedWriter out = null;
        try {
            out = new BufferedWriter(new FileWriter(certFile));
            out.write(certificate.getEncoded().toString());
        } catch ( Exception e ) {
            e.printStackTrace();
        } finally {
            if ( out != null ) out.close();
        }
        return cert;

    }catch (Exception e) {
        System.out.println("Error : " + e.getMessage());
    }
    return null;
}

Now when I run this, the .jks and .cer files are created but when I try to check the keystore with cmd command I get the error :

Command - keytool -list -keystore keyStore.jks

keytool error: java.io.IOException: Invalid keystore format

and

Command - keytool -printcert -v -file Cert.cer

keytool error: java.lang.Exception: Empty input
java.lang.Exception: Empty input
        at sun.security.tools.KeyTool.printCertFromStream(KeyTool.java:2234)
        at sun.security.tools.KeyTool.doPrintCert(KeyTool.java:2423)
        at sun.security.tools.KeyTool.doCommands(KeyTool.java:1069)
        at sun.security.tools.KeyTool.run(KeyTool.java:340)
        at sun.security.tools.KeyTool.main(KeyTool.java:333)

Any pointers about where I might be going wrong?

Upvotes: 0

Views: 1810

Answers (1)

user207421
user207421

Reputation: 311022

protected void getKeyStore(X509Certificate certificate)
{
    File newSnKeyStoreFile = new File("Mypath..\\keyStore.jks");

    try {

        KeyStore keyStore = KeyStore.getInstance("JKS");
        keyStore.load(null, null);

        if(!certificate.toString().isEmpty())

This test is pointless. If you have a certificate, its string representation won't be empty. If you don't, you shouldn't be calling this method at all. Remove.

        {
            keyStore.store(new FileOutputStream(newSnKeyStoreFile), "password".toCharArray());

Why? There's nothing in it yet. Remove.

            if (keyStore.getCertificateAlias(certificate) == null) {
                keyStore.setCertificateEntry("cert"+ count++, certificate);

And if it isn't null you should either overwrite the entry anyway or throw an exception, instead of silently ignoring the condition.

            }
        }
        keyStore.store(new FileOutputStream(newSnKeyStoreFile), KEYSTORE_PASSWORD.toCharArray());

Very good but you need to close this FileOutputStream.

        // Write to .jks file
        BufferedWriter out = null;
        try {
            out = new BufferedWriter(new FileWriter(newSnKeyStoreFile));
            out.write(keyStore.toString());
        } catch ( Exception e ) {
            e.printStackTrace();
        } finally {
            if ( out != null ) out.close();
        }

Remove all this pointless junk. You've already stored the keystore. All you're accomplishing here is corrupting it.

   File certFile = new File("Mypath..\\Cert.cer");
    // Write to .cer file
    BufferedWriter out = null;

Wrong. A certificate file is binary. Use a FileOutputStream.

    try {
        out = new BufferedWriter(new FileWriter(certFile));

Wrong, see above. out = new FileOutputStream(certFile);

        out.write(certificate.getEncoded().toString());

Wrong again. This should be

out.write(certificate.getEncoded());

You seem to have a mania for converting things to Strings. Try to taper off.

Upvotes: 1

Related Questions