Create signature with bouncycastle api. Key always null - java

I'm using bouncycastle for generating detached signature for XML's signing. For key initialize I use this code:
Security.addProvider(new BouncyCastleProvider());
KeyStore ks = KeyStore.getInstance(KEYSTORE_INSTANCE);
ks.load(new FileInputStream(KEYSTORE_FILE), KEYSTORE_PWD.toCharArray());
Key key = ks.getKey(CERT_ALIAS, KEYSTORE_PWD.toCharArray());
I have JKS keystore with certificate. But if I do this:
Key key = ks.getKey(CERT_ALIAS, KEYSTORE_PWD.toCharArray());
key stay always null and I have InvalidKeyException
Where's my mistake? I new in crypto

I can't comment due to too low reputation. So I'll answer/edit instead.
The above example works fine, the error is probably in one of the constants being used. What are they, and what is the exact error you're getting?
I mean something like: java.security.InvalidKeyException: Illegal key size
Here is the working example I tried while loading a KeyStore from a file:
'secret1' is the store password, 'secret2' is the key password and 'myKey' is the key alias.
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(new FileInputStream(keyStoreFile.getAbsolutePath()), "secret1".toCharArray());
Key key = keyStore.getKey("myKey", "secret2".toCharArray());

Related

Insert Public Key into a KeyStore programatically

I want to generate a key pair and insert the public and private keys into different keystores, to be used as KeyStore and TrustStore in an SSL Socket connection. I generate the KeyPair using a KeyPairGenerator, and I already have generated a signing certificate for the chain using java's keytool. Then I can insert the private key into a KeyStore like this:
PublicKey publicKey;
PrivateKey privateKey;
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, "storepass".toCharArray());
keyStore.setKeyEntry("privatekey", privateKey, "keypass".toCharArray(), chain);
Using this keystore I can create a KeyManager for the SSL connection. But to create a TrustManager, I need the public key stored into a KeyStore as well, so I tried storing the public key in a key store:
PublicKey publicKey;
KeyStore trustStore = KeyStore.getInstance("JKS");
keyStore.load(null, "storepass".toCharArray());
trustStore.setKeyEntry("publickey", publicKey, "public".toCharArray(), chain);
This returns an error: java.security.KeyStoreException: Cannot store non-PrivateKeys
So I tried using setCertificateEntry(), but this doesn't work since it's a PublicKey object and I need a Certificate. So my question is, how can I store the PublicKey in a KeyStore programatically? Using keytool is not an option.

BadPaddingException loading p12 keystore

When executing the following code:
KeyStore ks = KeyStore.getInstance(storeType);
ks.load(new FileInputStream(keyStore), storePassword.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, keyPassword.toCharArray());
I get an exception:
java.security.UnrecoverableKeyException: Get Key failed: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
This was originally from a JKS keystore converted to a PKCS12 keystore using keytool. I tried creating a new fresh PKCS12 keystore but no luck.
JKS supports using two passwords, one for the store and one for the key inside. PKCS12 uses the same password for both. When using the keytool, you'll get a warning about this.
When migrating to the new keystore, the code will likely continue using one password for the keystore, and another (different) password for the key, though now that won't work.
Java 9 gives a much better exception message around this indicating it might arise from a bad key during decryption.
In this case, make sure to pass in a key password that matches the store password.

Rename JKS alias with java programmatically

I would like to know how can I rename an alias of a keystore, programmatically in java, not using keytool.
I have my java.security.KeyStore object, containing an certain alias. How can I rename it?
The KeyStore API does not provide a rename operation for aliases. But what you can do is:
Save the content (key pair, certificates) of the keystore entry that you want to rename.
Delete the entry.
Create a new entry with the saved content and the new alias.
As Java code:
Key privateKey = keyStore.getKey(alias, password.toCharArray());
Certificate[] certs = keyStore.getCertificateChain(alias);
keyStore.setKeyEntry(newAlias, privateKey, password.toCharArray(), certs);
keyStore.deleteEntry(alias);
Of course this does not work if the private key is stored on a hardware device (smartcard or HSM) and therefore is not readable.
If the keystore entry contains a trusted certificate, the code looks a bit different:
Certificate cert = keyStore.getCertificate(alias);
keyStore.setCertificateEntry(newAlias, cert);
keyStore.deleteEntry(alias);

Storing an X.509 certificate into a keystore using java code

I have an X.509 certificate created using bouncycastle library. How can I store it into a java Keystore?
I tried this code
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
// get user password and file input stream
char[] password = getPassword();
java.io.FileInputStream fis =
new java.io.FileInputStream("keyStoreName");
ks.load(fis, password);
fis.close();
I found this code here, but the key store created using this way does not work with keytool, it tells me the keystore is corrupted.
Use KeyStore.setCertificateEntry(alias, cert) and give it an alias name of your choice. Then, use KeyStore.store(...) to save the keystore (typically using a FileOutputStream).

What Is The Best Keystore to use?

I want to use Keystore in my upcoming project. I saw that there is an Keystore API in Java. But that seems to be very complicated.
Are there any other good keystore available that work well with Java/Groovy?
Not that I know of. From my perspective, the API is relatively as minimal as possible give the things that it needs to supply.
KeyStore keyStore = keyStore.getInstance(KeyStore.getDefaultType());
keyStore.load( inputStream, storePassword.getBytes() );
// Get a key
if ( keyStore.isKeyEntry(alias) ) {
Key key = keyStore.getKey(alias, keyPassword.getBytes());
}
// Store a new key
KeyFactory keyFactory = KeyFactory.getInstance(KeyStore.getDefaultType());
KeySpec keySpec ...; // depends on what kind of key you want to create (ie. rsa, etc..)
Key key = keyFactory.generatePrivate(keySpec);
// sign the key here
Certificate certChain[] = ...; // get the cert chain
keyStore.setKeyEntry(newAlias, newKey, newKeyPassword.getBytes(), certChain);
keyStore.store(outputStream, storePassword.getBytes());
This is relatively minimal code to handle what a keystore needs to do.

Categories