19

I've need to store 2 keys into KeyStore Here's the relevant code:

KeyStore ks = KeyStore.getInstance("JKS");
String password = "password";
char[] ksPass = password.toCharArray();
ks.load(null, ksPass);
ks.setKeyEntry("keyForSeckeyDecrypt", privateKey, null, null);
ks.setKeyEntry("keyForDigitalSignature", priv, null, null);
FileOutputStream writeStream = new FileOutputStream("key.store");
ks.store(writeStream, ksPass);
writeStream.close();

Though I get an execption "Private key must be accompanied by certificate chain"

What is that, exactly? and how would I generate it?

Jens Björnhager
  • 5,632
  • 3
  • 27
  • 47
MichBoy
  • 299
  • 1
  • 4
  • 13

1 Answers1

19

You need to also provide the certificate (public key) for the private key entry. For a certificate signed by a CA, the chain is the CA's certificate and the end-certificate. For a self-signed certificate you only have the self-signed certificate
Example:

KeyPair keyPair = ...;//You already have this  
X509Certificate certificate = generateCertificate(keyPair);  
KeyStore keyStore = KeyStore.getInstance("JKS");  
keyStore.load(null,null);  
Certificate[] certChain = new Certificate[1];  
certChain[0] = certificate;  
keyStore.setKeyEntry("key1", (Key)keyPair.getPrivate(), pwd, certChain);  

To generate the certificate follow this link:
Example:

public X509Certificate generateCertificate(KeyPair keyPair){  
   X509V3CertificateGenerator cert = new X509V3CertificateGenerator();   
   cert.setSerialNumber(BigInteger.valueOf(1));   //or generate a random number  
   cert.setSubjectDN(new X509Principal("CN=localhost"));  //see examples to add O,OU etc  
   cert.setIssuerDN(new X509Principal("CN=localhost")); //same since it is self-signed  
   cert.setPublicKey(keyPair.getPublic());  
   cert.setNotBefore(<date>);  
   cert.setNotAfter(<date>);  
   cert.setSignatureAlgorithm("SHA1WithRSAEncryption");   
    PrivateKey signingKey = keyPair.getPrivate();    
   return cert.generate(signingKey, "BC");  
}
Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • the public key is of type Key, and they request Certificate[]. How would I cast the public key to Certificate Chain – MichBoy Dec 15 '12 at 18:11
  • Don't you have a `X509Certificate`?Where did you get the private key? – Cratylus Dec 15 '12 at 18:13
  • I've initialized a KeyPairGenerator to generate pair of keys – MichBoy Dec 15 '12 at 18:14
  • 2
    You need to use a `X509V3CertificateGenerator` to create a certificate which you will pass as a parameter to the keystore as part of you private key entry http://www.bouncycastle.org/wiki/display/JA1/X.509+Public+Key+Certificate+and+Certification+Request+Generation – Cratylus Dec 15 '12 at 18:16
  • hmm...ok I'll try to understand from the link. Thanks – MichBoy Dec 15 '12 at 18:18
  • If you need help let me know.Since this is homework I will let you try out yourself first – Cratylus Dec 15 '12 at 18:20
  • The homework is actually an exercise to pracitice on Java Crypto API, using JCA and JCE classes. We haven't disscussed about those certificates, but in the exercise we are requested to store the private keys we've generated inside a password-protected KeyStore. So I'll be happy to recieve further help, please :) – MichBoy Dec 15 '12 at 18:22
  • You can not store a private key in a keystore without the certifying chain.You need to generate the corresponding certificate and add it along the private key in the keystore – Cratylus Dec 15 '12 at 18:25
  • So can I please get further help with this? – MichBoy Dec 15 '12 at 18:27
  • Thanks alot @Cratylus!! Though all te setters doesn't seem to be exist – MichBoy Dec 15 '12 at 18:51
  • Use `org.bouncycastle.x509.X509V3CertificateGenerator`. They exist – Cratylus Dec 15 '12 at 18:54
  • My eclipse doesn't recognize org.bouncycastle as something I can import, how would I get it? – MichBoy Dec 15 '12 at 18:56
  • You need to have bouncy castle library in your build path – Cratylus Dec 15 '12 at 18:57
  • 2
    @Cratylus You say `KeyPair keyPair = ...;//You already have this `. I don't have it! I want it! Where can I get it? – Tomáš Zato Mar 18 '15 at 07:43
  • 7
    This is a nice solution. However, I am not allowed to use bouncy castle, only standard Java 8 JCE libraries. What to do? – Andy Nov 05 '16 at 16:33