Java JKS API: keyStore is empty - java

I'm trying to get my PKI material using KeyStore API. The content of my keystore is:
My code is:
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(this.getClass().getResourceAsStream(this.boConfiguration.getUiPortalAdminKeyStore()),
this.boConfiguration.getUiPortalAdminKeyPassword().toCharArray()
);
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
LOG.debug(aliases.nextElement());
}
Key pK = ks.getKey(
"gestio",
this.boConfiguration.getUiPortalAdminKeyStorePassword().toCharArray()
);
Key pKey = ks.getKey("gestio", this.boConfiguration.getUiPortalAdminKeyStorePassword().toCharArray());
Certificate[] certs = ks.getCertificateChain("gestio");
Certificate cert = ks.getCertificate("gestio");
My problem is that all ks.get* returns me null. However, keystore is not empty. Also, getAlias method returns me an empty enumeration.
Any ideas?
This is the content according keystore explorer:

Related

Get the Entry type of a KeyStore programatically

With the keytool command, we have this kind of information:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: myname
Creation date: 21-Aug-2011
Entry type: PrivateKeyEntry
Certificate chain length: 1
...
In Java (programatically), how can I retrieve the "Entry type" value to know if it's a private certificate or a public? I'm using the KeyStore Java class this way:
File file = new File(filePath);
String password = password.toCharArray();
KeyStore keyStore = KeyStore.getInstance(format);
keyStore.load(new FileInputStream(file), password);
What you need to do is check if the KeyEntry for the given alias in the KeyStore is a PrivateKeyEntry or a TrustedCertificateEntry.
char[] password = "mypassword";
ProtectionParameter passwordProtection = new KeyStore.PasswordProtection(password.toCharArray());
KeyEntry entry = keystore.getEntry("myname", passwordProtection);
if (entry instanceof PrivateKeyEntry) {
// is a private key entry
}

Digital Signature for Acrobat

Trying to get an authenticated digital signature onto a PDF in Acrobat, by using iText. The way we want to grab someone digital signature is through there cert, which in our case we would be getting the user cert through their CAC's. Having issue with the ks.load() where I am getting an error: "Invalid key store format". Wonder if it is even possible without using any cmd? Would prefer a solution that involves Java.
String KEYSTORE = ReadConfig.get("WebRoot")+"mods/Reports/sources/t_cert.jks";
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(KEYSTORE), null);
String alias = (String) ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, null);
Certificate[] chain = ks.getCertificateChain(alias);

How does one correctly create and access a KeyStore in java to store an encryption key?

I've been mixing and matching code, trying to learn by example for using KeyStores.
I have this createKeyStore method:
private static KeyStore createKeyStore(String fileName, String pw) throws Exception
{
File file = new File(fileName);
final KeyStore keyStore = KeyStore.getInstance("JCEKS");
if (file.exists())
{
// .keystore file already exists => load it
keyStore.load(new FileInputStream(file), pw.toCharArray());
}
else
{
// .keystore file not created yet => create it
keyStore.load(null, null);
keyStore.store(new FileOutputStream(fileName), pw.toCharArray());
}
return keyStore;
}`
It seems to work, no errors are thrown.
I am then trying to access the code by:
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(new FileInputStream(keystorePath), pass.toCharArray());
String alias = "alias";
char[] password = pass.toCharArray();
Certificate cert = keystore.getCertificate(alias);
keystore.setCertificateEntry(alias, cert);
// Save the new keystore contents
FileOutputStream out = new FileOutputStream(keystoreFile);
keystore.store(out, password);
out.close();
But my call to keystore.load throws an Invalid Keystore Format exception.
I tried to replace the FileInputStream with null, but it seems to throw an error setting the certificate.
TL;DR: I am only trying to store a few encryption keys in this keystore, but I can't seem to access it correctly.
Thanks for reading!
You have:
final KeyStore keyStore = KeyStore.getInstance("JCEKS");
and
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
Change these so they agree.
This:
Certificate cert = keystore.getCertificate(alias);
keystore.setCertificateEntry(alias, cert);
is pointless. If there wasn't such a certificate in the keystore, it will fail, and if there was, it will just replace it with itself. What's the point exactly?
I tried to replace the FileInputStream with null
I cannot imagine why. There's nothing in the Javadoc that suggests that will work.
If you look at the documentation it says to create an empty keystore call the load() method with null as the file input parameter but not the password parameter. Passing null as the password parameter in your else clause causes null pointer exceptions when loading the keystore from file later.
keystore.load(null, pass.toCharArray());

Checking for CA's certificate before entering a certificate?

I am inserting a client certificate into my servertruststore using following code
FileInputStream fileInputStream = new FileInputStream( "c:/server.jks" );
keyStore.load( fileInputStream, "keystore".toCharArray() );
fileInputStream.close();
keyStore.setCertificateEntry( alias, new X509Certificate( trustedCertificate ) );
FileOutputStream fileOutputStream = new FileOutputStream("c:/server.jks" );
keyStore.store( fileOutputStream, "keystore".toCharArray() );
fileOutputStream.close();
Now i see that certificate is entered into my truststore but the CA's certificate which signed client's certificate is not present in my truststore. So I want to know is there any way we can check whether the certificate of CA is available or not before entering a certificate into keystore?
I guess what you have to do is to verify if the certificate has been issued by a root authority or it has been self-signed. I presume you are using the default java keystore which is cacerts.
I haven't tested the code but I think this may be a solution to your problem:
Code taken and modified from the following link:
How can I get a list of trusted root certificates in Java?
String filename = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar);
Set<X509Certificate> additionalCerts = new HashSet<X509Certificate>();
FileInputStream is = new FileInputStream(filename);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
String password = "changeit";
keystore.load(is, password.toCharArray());
// This class retrieves the most-trusted CAs from the keystore
PKIXParameters params = new PKIXParameters(keystore);
// Get the set of trust anchors, which contain the most-trusted CA certificates
Iterator it = params.getTrustAnchors().iterator();
while( it.hasNext() ) {
TrustAnchor ta = (TrustAnchor)it.next();
// Get certificate
X509Certificate cert = ta.getTrustedCert();
additionalCerts.add(cert);
}
Then you may use the following code to pass the client certificate and the Set containing all the root CAs to the verifyCertificate(X509Certificate cert, Set additionalCerts) method of the following code:
http://www.nakov.com/blog/2009/12/01/x509-certificate-validation-in-java-build-and-verify-chain-and-verify-clr-with-bouncy-castle/

How to store and load keys using java.security.KeyStore class

After creating secret keys, how do I store them using the Keystore class' methods and how do I load the keys?
Storing:
KeyStore ks = KeyStore.getInstance("JKS");
ks.setKeyEntry("keyAlias", key, passwordForKeyCharArray, certChain);
OutputStream writeStream = new FileOutputStream(filePathToStore);
ks.store(writeStream, keystorePasswordCharArray);
writeStream.close();
Note thet certChain might be null, unless you are passing PrivateKey
Loading:
KeyStore ks = KeyStore.getInstance("JKS");
InputStream readStream = new FileInputStream(filePathToStore);
ks.load(readStream, keystorePasswordCharArray);
Key key = ks.getKey("keyAlias", passwordForKeyCharArray);
readStream.close();
Read the javadocs
EDIT:
Note that if you are storing a SecretKey or using any part of the SunJCE provider (Java Cryptography Extension), you will need to set your KeyStore type to JCEKS.
KeyStore ks = KeyStore.getInstance("JCEKS");
I had a situation where I didn't know the key alias name, but I knew there was only one key was there in the keystore. I used the following code to load the key (after loading the keystore as shown above):
Enumeration<String> aliases = keyStore.aliases();
String alias = aliases.nextElement();
KeyStore.PrivateKeyEntry keyEnt = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias,
new KeyStore.PasswordProtection(keystorePass.toCharArray()));
PrivateKey privateKey = keyEnt.getPrivateKey();
I have added a post on my blog with details of how to load the private key, public key and how to use them.

Categories

Resources