2

I have created a keystore using the java keytool to store a passowrd using the following command

$ keytool -importpassword -alias myalias -keystore mykeystore.jceks -storetype jceks 
Enter keystore password:  keystore
Re-enter new password: keystore
Enter the password to be stored: testpassword 
Re-enter password: testpassword
Enter key password for <myalias>
    (RETURN if same as keystore password): 

I want to retrieve this password in a java program. Here's what I have written so far.

InputStream is = new FileInputStream(new File("mykeystore.jceks"));
KeyStore ks = KeyStore.getInstance("jceks");
ks.load(is, "keystore".toCharArray());
PasswordProtection pp = new PasswordProtection("keystore".toCharArray());
SecretKeyEntry ske = (SecretKeyEntry) ks.getEntry("myalias", pp);
System.out.println(ske.toString()); // Outputs: "Secret key entry with algorithm PBEWithMD5AndDES"

How can I get back the password I store? Is it even possible?

Complete reference code below.

Required libraries:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStore.PasswordProtection;
import java.security.KeyStore.SecretKeyEntry;

import java.security.cert.CertificateException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.UnrecoverableEntryException;

Class:

class JCEKS 
{  
    public static void main(String args[]) 
    {
        try{
            InputStream is = new FileInputStream(new File("mykeystore.jceks"));
            KeyStore ks = KeyStore.getInstance("jceks");
            ks.load(is, "keystore".toCharArray());
            PasswordProtection pp = new PasswordProtection("keystore".toCharArray());
            SecretKeyEntry ske = (SecretKeyEntry) ks.getEntry("myalias", pp);

            System.out.println(ske.toString());
        }
        catch(KeyStoreException e){
            System.out.println("KeyStoreException:");
            System.out.println(e);
        }
        catch(FileNotFoundException e){
            System.out.println("FileNotFoundException:");
            System.out.println(e.getMessage());
        }
        catch(IOException e){
            System.out.println("IOException:");
            System.out.println(e.getMessage());
        }
        catch(NoSuchAlgorithmException e){
            System.out.println("NoSuchAlgorithmException:");
            System.out.println(e.getMessage());
        }
        catch(CertificateException e){
            System.out.println("CertificateException:");
            System.out.println(e.getMessage());
        }
        catch(UnrecoverableKeyException e){
            System.out.println("UnrecoverableKeyException:");
            System.out.println(e.getMessage());
        }
        catch(UnrecoverableEntryException e){
            System.out.println("UnrecoverableEntryException:");
            System.out.println(e.getMessage());
        }
    } 
} 
  • You can't. It is hashed, not encrypted. You didn't store the password in the KeyStore, you created the KeyStore with the password. It isn't inside there in an entry. If you forgot it, bad luck. – user207421 Apr 12 '20 at 21:55
  • I see. Thank you for that clarification. No I didn't forget the password. I was under the impression that when I was prompted to enter a password to be stored, the password would be stored somewhere and I would be able to retrieve it if i provided the keystore password. – Ibraheem Ibraheem Apr 13 '20 at 02:19
  • To clarify: essentially what I am expecting (hoping) to get back is that "testpassword" phrase. – Ibraheem Ibraheem Apr 13 '20 at 02:27
  • Your impression would violate all known concepts of security. Life isn't like that, and it shouldn't be. A recoverable password is no security at all. – user207421 Apr 14 '20 at 10:23
  • 1
    The OP was referring to the password entry that can be store as secret key entry [-importpassword](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html#keytool_option_importpassword) – always_a_rookie Apr 14 '20 at 13:56

2 Answers2

1

The password entry you stored is stored as a SecretKeyEntry and its value can be retrieved using the getEncoded() method of the secretKey object.

System.out.println(new String(ske.getSecretKey().getEncoded()));

always_a_rookie
  • 4,515
  • 1
  • 25
  • 46
1

After some digging and some trial and error, it turns out you CAN retrieve a password that you store using keytool For example, if you use the following command to store a password

    > $ keytool -importpassword -alias my-alias -keystore my-keystore.jcek -storetype jceks

    > Enter keystore password:  keystorepassword 
    > Re-enter new password:keystorepassword 
    > Enter the password to be stored: thepassword
    > Re-enter password: thepassword 
    > Enter key password for <my-alias>
        (RETURN if same as keystore password): keypassword 
    > Re-enter new password: keypassword

To retrieve the password your stored (i.e. 'thepassword'):

InputStream is = new FileInputStream(new File("my-keystore.jceks"));
KeyStore ks = KeyStore.getInstance("JCEKS");
ks.load(is, "keystorepassword".toCharArray());
PasswordProtection pp = new PasswordProtection("keypassword".toCharArray());
SecretKeyEntry ske = (SecretKeyEntry) ks.getEntry("my-alias", pp);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHMD5ANDDES");
PBEKeySpec keySpec = (PBEKeySpec) factory.getKeySpec(ske.getSecretKey(), PBEKeySpec.class);
String password = new String(keySpec.getPassword());
System.out.println(password);

Output: thepassword

Note that when you store a string, it defaults to PBEWITHMD5ANDDES algorithm. So you will need to download the javax-crypto.jar and compile it along with your program javac -cp javax-crypto.jar your-program.java