Java Security: Keys

1. GENERATING KEYS

Though Java’s keytool utility is a powerful tool for key generation and manipulation, Java provides some useful classes and interfaces to work with both public and secret keys.

1.1. Public Key Generation

A public key is generated using java.security.KeyGenerator class as follows:

String alg = “RSA”;

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getlnstance(alg);

KeyPair keyPair = keyPairGenerator.genKeyPair();

PrivateKey pri = keyPair.getPrivate();

PublicKey pub = keyPair.getPublic();

This generates a private and public key pair using RSA algorithm with default parameters. The overloaded initialize() methods of KeyPairGenerator class may be used to specify algorithm- specific parameters such as key length, randomness etc. Currently, the supported public key generation algorithms are RSA, DSA, EC and DiffieHellman (or simply DH).

1.2. Private Key Generation

The class javax.crypto.KeyGenerator is used to generate secret (symmetric) keys which are used in secret key cryptography. The following generates a key using DES algorithm:

KeyGenerator generator = KeyGenerator.getInstance(”DES”);

SecretKey secretKey = generator.generateKey();

The overloaded init() methods of KeyGenerator class may be used to specify algorithm specific parameters such as key length, randomness etc. Currently, the supported secret key generation algorithms are DES, AES, ARCFOUR, Blowfish, DESede, HmacSHAl, HmacSHA256, HmacSHA384, HmacSHA512 and RC2.

2. WORKING WITH KEYSTORE

A keystore, in Java, is represented by a java.security.KeyStore instance, which is created using its static getinstance() method specifying keystore type and optionally a provider:

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

This creates a KeyStore object of type as specified in the Java security properties file. The following creates a KeyStore object of specified type “jks”.

KeyStore ks = KeyStore.getInstance(”jks”);

Specify keystore type “jceks” or “pkcs12” (case-insensitive) in getInstance() method for JCEKS and PKCS12 type keystores respectively.

2.1. Reading Keystore

The following program reads a JKS-type keystore file and prints information about all the entires:

import java.io.*;

import java.util.*;

import java.security.*;

import java.security.cert.Certificate;

public class ReadJKS {

public static void main(String[] args) throws Exception {

char[] password = args[1].toCharArray();

KeyStore ks = KeyStore.getInstance(”JKS”);

ks.load(new FileInputStream(args[0]), password);

Enumeration e = ks.aliases();

while(e.hasMoreElements()) {

String alias = (String)e.nextElement();

KeyStore.ProtectionParameter protParam = new

KeyStore.PasswordProtection(password);

KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)ks.getEntry(alias, protParam);

PrivateKey pri = pkEntry.getPrivateKey();

System.out.println(pri);

java.security.cert.Certificate[] certs = pkEntry.getCertificateChain();

for(java.security.cert.Certificate cert:certs)

System.out.println(cert);

}

}

}

2.2. Extracting Private Keys from Keystore

The keytool command does not allow us to extract the private key from a key store. A simple Java program may be written to do this. The following program gets the key and the corresponding certificate and saves them in files key.der and cert.der in DER format:

import java.io.*;

import java.security.*;

public class ReadKeyStore {

public static void main(String[] args) throws Exception {

char[] password = ”123456”.toCharArray();

KeyStore ks = KeyStore.getInstance(”JKS”);

ks.load(new FileInputStream(args[0]), password);

String alias =”mykey”;

FileOutputStream kos = new FileOutputStream(”key.der”);

Key pri = ks.getKey(alias, password);

kos.write(pri.getEncoded());

FileOutputStream cos = new FileOutputStream(”cert.der”);

java.security.cert.Certificate cert = ks.getCertificate(alias);

cos.write(cert.getEncoded());

}

}

Use the following command to create a keystore test.jks:

keytool -genkey -keystore test.jks -dname “CN=Test, OU=IT, O=JU, L=Kolkata, ST=WB, C=IN”

Run the above Java program as follows:

java ReadKeyStore test.jks

These private keys and certificates may be used in other applications.

2.3. Storing Private Key and Certificate in Keystore

The following program creates an entry in the key store file aStore.jks from a given key and a certificate file. These key and certificates may be generated using the previous program.

import java.security.*;

import java.io.*;

import java.security.spec.*;

import java.security.cert.Certificate;

import java.security.cert.CertificateFactory;

import java.util.*;

public class WriteKeyStore {

public static void main ( String args[]) throws Exception {

char[] password = ”123456”.toCharArray();

String alias = ”aKey”, name = “aStore.jks”;

KeyStore ks = KeyStore.getInstance(”JKS”, “SUN”);

ks.load( null , password);

FileInputStream fis = new FileInputStream(args[0]);

byte[] kdata = new byte[fis.available()];

fis.read(kdata);

PKCS8EncodedKeySpec kp = new PKCS8EncodedKeySpec (kdata);

KeyFactory kf = KeyFactory.getInstance(”DSA”);

PrivateKey pri = kf.generatePrivate (kp);

CertificateFactory cf = CertificateFactory.getInstance(”X.509”);

Collection c = cf.generateCertificates(new FileInputStream(args[1])) ;

Certificate[] certs = new Certificate[c.size()];

int in = 0;

for(Iterator i = c.iterator(); i.hasNext();)

certs[in++] = (Certificate)i.next();

ks.setKeyEntry(alias, pri, password, certs );

ks.store(new FileOutputStream ( name ),password);

System.out.println (”Key and certificate stored.”);

}

}

Run the above Java program as follows:

java WriteKeyStore key.der cert.der

These stores may be used in other applications.

Source: Uttam Kumar Roy (2015), Advanced Java programming, Oxford University Press.

Leave a Reply

Your email address will not be published. Required fields are marked *