void createKeyStore(String alias) throws Exception {
if(keyStoreType == null || keyStoreType.isEmpty()){
keyStoreType = KeyStore.getDefaultType();
}
keyStore = KeyStore.getInstance(keyStoreType);
KeyPair kp = generateRSAKeyPair();
Certificate[] certChain = new Certificate[1];
certChain[0] = generateCertificate(kp);
//load
char[] pwdArray = keyStorePassword.toCharArray();
keyStore.load(null, pwdArray);
keyStore.setKeyEntry(alias, kp.getPrivate(), keyStorePassword.toCharArray(), certChain);
// Save the keyStore
FileOutputStream fos = new FileOutputStream(keyStoreName,true);
keyStore.store(fos, pwdArray);
fos.close();
}
Using this function for create and write multiple alias in keystore
In the first request it create keystore file and store the alias with private key and certificate but in the second request with alias it not storing any data in same keystore file.
I am working on a Java project. I have created certificate using my function but now I have only one certificate . I am expecting to store multiple alias in the same file but it happen only with first request but not with second request.
Below is my code for getting private key from Keystore file.
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
System.err.println(KeyStore.getDefaultType());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(new FileInputStream("src/main/resources/xxx.jks"), PASSWORD);
String alias = "xxxxxxx";
PrivateKey pk = (PrivateKey) ks.getKey(alias, PASSWORD);
System.err.println(pk);
I am giving right values for alias and password. But I am getting null in private key.
Why I am getting null, Is there any alternative approach to get private key from jks file.
Any help will be greatly appreciated!!
My question is not able to get the private key. But the mentioned question is the incorrect key
I would like to save a X509Certificate and its private key into the Android KeyStore, I tought I should 'merge' the X509Certificate (containing the public key) and its private key. The private key is used to create a CSR and then a server party sign the certificate and return to the application, can I merge the cert and the private key into one unique cert? Also I'm using spongycastle (aka bouncycastle's android wrapper).
I have no idea about Android KeyStore, but maybe you can try something like:
PrivateKey privateKey = ... //this is what you already have
X509Certificate certificate = ... //this is what you already have
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
Certificate[] certChain = new Certificate[1];
certChain[0] = certificate;
char[] myKeyPassword = "myKeyPassword".toCharArray();
keyStore.setKeyEntry("mykeyalias", (Key)privateKey, myKeyPassword, certChain);
See https://docs.oracle.com/javase/9/docs/api/java/security/KeyStore.html#setKeyEntry-java.lang.String-java.security.Key-char:A-java.security.cert.Certificate:A- for more information about KeyStore.setKeyEntry
I need to convert a JKS (password protected) in to a .PEM containing the KeyPairs (or selected alias) for other services to use.
So far, I have written this:
#Transactional
public ResponseEntity<String> getPublicKeyFromJKS(long jksid) {
try {
//1. Lift the entity
JKSFile jksFile = jksFileRepo.getOne(jksid);
//2. Get the Object from S3
S3Object object = getS3ObjectService.getS3Object(jksFile.getS3ObjectKey());
System.out.println(object.getObjectContent().getHttpRequest());
InputStream in = object.getObjectContent();
//3. Make KeyStore...
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(in, rsaConfig.getKeystorePassword().toCharArray());
//4. Get keys to PEM formatted file.
PrivateKey privateKey = (PrivateKey) keyStore.getKey("access", rsaConfig.getKeystorePassword().toCharArray());
Certificate certificate = keyStore.getCertificate("access");
PublicKey publicKey = certificate.getPublicKey();
KeyPair keyPair = new KeyPair(publicKey, privateKey);
System.out.println(keyPair.getPrivate().toString());
System.out.println(keyPair.getPublic().toString());
I am pulling the requested JKS from my amazon S3 bucket and reading the Private and Public key without issue...but I would now like to be able to put them in to a PEM formatted keystore (for use by another service).
Thanks for any suggestions! I want this programatically...not using the java command line keytool.
I have a file on my FS (a S3 AWS key) that contains a string that is a key I use for encryption process.
I would like to move it a Java KeyStore.
I know how to import a certificate into a KeyStore with keytool but I can't find the way to import a simple string key.
Can you help?
You can do this with PBE and JCEKS. I don't think you can do it with JKS.
Solution:
Create a keystore to store and get entries from:
keytool -keystore clientkeystore -genkey -alias client -storetype jceks
Now some code to test it out.
public static String getPasswordFromKeystore(String entry, String keystoreLocation, String keyStorePassword) throws Exception{
KeyStore ks = KeyStore.getInstance("JCEKS");
ks.load(null, keyStorePassword.toCharArray());
KeyStore.PasswordProtection keyStorePP = new KeyStore.PasswordProtection(keyStorePassword.toCharArray());
FileInputStream fIn = new FileInputStream(keystoreLocation);
ks.load(fIn, keyStorePassword.toCharArray());
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");
KeyStore.SecretKeyEntry ske =
(KeyStore.SecretKeyEntry)ks.getEntry(entry, keyStorePP);
PBEKeySpec keySpec = (PBEKeySpec)factory.getKeySpec(
ske.getSecretKey(),
PBEKeySpec.class);
char[] password = keySpec.getPassword();
return new String(password);
}
public static void makeNewKeystoreEntry(String entry, String entryPassword, String keyStoreLocation, String keyStorePassword)
throws Exception {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");
SecretKey generatedSecret =
factory.generateSecret(new PBEKeySpec(
entryPassword.toCharArray()));
KeyStore ks = KeyStore.getInstance("JCEKS");
ks.load(null, keyStorePassword.toCharArray());
KeyStore.PasswordProtection keyStorePP = new KeyStore.PasswordProtection(keyStorePassword.toCharArray());
ks.setEntry(entry, new KeyStore.SecretKeyEntry(
generatedSecret), keyStorePP);
FileOutputStream fos = new java.io.FileOutputStream(keyStoreLocation);
ks.store(fos, keyStorePassword.toCharArray());
}
I had to do this this afternoon, the solution of #JasonG works but not the keytool options.
Since Java 8 you can use the -importpass option with Keytool, which will help you achieve what you need.
Let's suppose I want to save the sensitive password foobar in the mypass alias in the keystore named myks.jceks protected with the password password here, do the following:
$ keytool -importpass -storetype pkcs12 -alias mypass -keystore myks.p12
Enter keystore password: <password>
Re-enter new password: <password>
Enter the password to be stored: <foobar>
Re-enter password: <foobar>
Enter key password for <mypass>
(RETURN if same as keystore password): <password>
Re-enter new password: <password>
And then you're good to go to use the same code as #JasonG, I have this in my code:
private Try<String> loadKey(Resource path, String pw) {
return Try.of(() -> {
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(path.getInputStream(), pw.toCharArray());
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");
SecretKeyEntry ske = (SecretKeyEntry) ks.getEntry("mypass",
new PasswordProtection(pw.toCharArray()));
PBEKeySpec keySpec = (PBEKeySpec) factory.getKeySpec(
ske.getSecretKey(), PBEKeySpec.class);
return new String(keySpec.getPassword());
});
}
Note that I have used PKCS12 since JCEKS uses a proprietary format, and it is recommended to migrate to PKCS12 which is an industry standard format.
Besides we had some problems with some Windows machine (running Java 8) being stuck while trying to load the JCEKS store, throwing exceptions. PKCS12 seems a better choice.
I don't see a way to do it with keytool, but some poking about, I wonder if you could store and retrieve it in code as a PasswordBasedEncryption (PBE) SecretKey. (Disclaimer: I haven't tried this myself).
The resources that drove this thought:
PBEKeySpec javadoc and CryptoSpec - Using Password Based Encryption example
I know this is old; but I came across this same use case.
https://docs.oracle.com/javase/9/tools/keytool.htm#JSWOR-GUID-5990A2E4-78E3-47B7-AE75-6D1826259549
keystores have an importpass options that stores a KeyStore.SecretKeyEntry identified by alias.
So there's that and you could store your string in an alias.
You can not import in the key store arbitrary strings. In the key store you import certification keys that java libraries are using for authentication of remote hosts.