0

How do I programmatically create a private key and use it in a SSL socket?

I put a commented exception below where I'm trying to add the key to the keystore but I do not have a certificate chain.

    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
    keyGen.initialize(1024, new SecureRandom());
    KeyPair keypair = keyGen.generateKeyPair();

    System.setProperty("javax.net.ssl.keyStore", System.getProperty("user.home")
        + File.separator +
            + "/keystore.jks");
    System.setProperty("javax.net.ssl.keyStorePassword", "xyz");

    KeyManagerFactory keyManagerFactory = KeyManagerFactory
            .getInstance("SunX509");
    KeyStore keyStore = KeyStore.getInstance("JKS");
    keyStore.load(null, "xyz".toCharArray());

    //setKeyEntry parameter 3 can not be null: 
    //IllegalArgumentException: Private key must be accompanied by certificate chain
    keyStore.setKeyEntry("alias", keypair.getPrivate(),
            "xyz".toCharArray(), null);

    keyManagerFactory.init(keyStore, "xyz".toCharArray());
    // keyStore.load
    SSLContext context = SSLContext.getInstance("TLS");// "SSLv3"
    context.init(keyManagerFactory.getKeyManagers(), null,
            new SecureRandom());
    ServerSocketFactory socketFactory = context.getServerSocketFactory();
    ServerSocket ssocket = socketFactory.createServerSocket(1443);
    Socket socket = ssocket.accept();
jcalfee314
  • 4,642
  • 8
  • 43
  • 75
  • I almost have it(keyStore.setKeyEntry("alias", keypair.getPrivate(), "xyz".toCharArray(), null)) but, the last parameter is a required certificate chain, but I don't have a certificate chain. ... I don't want the extra JARs, but I may have to include bouncycastle to do this: http://blog.thilinamb.com/2010/01/how-to-generate-self-signed.html – jcalfee314 Jul 25 '12 at 20:53
  • HI Alen, the question is: how do I programmatically create a private key and use it in a SSL socket? – jcalfee314 Jul 25 '12 at 20:57

1 Answers1

1

How do I programmatically create a private key and use it in a SSL socket?

There is little point creating only a private key, or even just a private/public key pair. What you need to set up on your server is a certificate associated with this private key.

X.509 certificates are rather complex structures, based on ASN.1 syntax. I'd strongly suggest you use BouncyCastle (more or less as described in the blog article you link to). Doing it all by hand is no simple task. (If you're not convinced, look at the source code of the BouncyCastle classes.)

In addition, there's little point in creating this certificate (and its associated private key) dynamically. The point of the certificate is to allow the client to verify the identity of the server it's talking to. The client does this by checking the server cert against a list of trusted certificates it has (either using a PKI or by individual comparison against specific server certificates that have been manually configured).

If you generate a self-signed certificate dynamically, there is no way for the client to compare it against something it would have known in advance. It could potentially be useful if your server is also a CA (for applications similar to MITM-proxy servers).

Bruno
  • 119,590
  • 31
  • 270
  • 376
  • What if I create the X.509 and include it in the program? There is no requirement to have a unique x509, just unique keys. By the way, I'll design this app to create new keys for new users and then allow them to link up an compare finger-prints. Each new connection requires two approves (one at each end). They will use text, phone, etc.. to authorize each other. So, it does not matter what CA I use, this should still be very secure. – jcalfee314 Jul 26 '12 at 13:32
  • If you have an external way to verify the keys, that's fine. It's just that even fingerprints can be a bit long in terms of usability when obtained by phone/text. Remember that certs also tie an identity to a key (so users would also need to know whose key it is). The X.509 cert contains the public key. You'll have to build the right DER structure and sign it manually (the opposite of the 2nd part of [this answer](http://stackoverflow.com/a/10414727/372643), which verifies the signature). Building a well-formed DER structure manually from the public key can be tedious (and prone to bugs). – Bruno Jul 26 '12 at 13:39
  • Turns out I did not have a requirement for a SSL socket. I'm going to work directly with cypher streams instead. Thanks for your help. I have a better understanding of the certificate chain. – jcalfee314 Jul 30 '12 at 13:01
  • @jcalfee314, handling cipher streams manually often turns out to be more complex and less secure than using proven SSL/TLS implementation. – Bruno Jul 30 '12 at 13:11