This java code works on Windows system with an acceptable speed (around 1 sec), but it takes up to 1 minute on Linux system.
After some investigation, I found it is also down to slow SecureRandom issue on Linux.
The workaround is easy, use the switch -Djava.security.egd=file:/dev/./urandom if you are using JRE 1.5+.
I did a test on CentOS(an ESXi VM), see how different the results are!
java -classpath .:bcprov.jar KeyPairCost ---- test start ---- Generate KeyPair takes 176 msec Store takes 58923 msec ---- test end ---- java -Djava.security.egd=file:/dev/./urandom -classpath .:bcprov.jar KeyPairCost ---- test start ---- Generate KeyPair takes 297 msec Store takes 404 msec ---- test end ----
Java Code
import java.io.ByteArrayOutputStream; import java.util.*; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.Security; import java.math.BigInteger; import java.security.cert.X509Certificate; import org.bouncycastle.x509.X509V1CertificateGenerator; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class KeyPairCost { static X509V1CertificateGenerator v1CertGen = new X509V1CertificateGenerator(); public static void generateKeyPairCost() throws Exception { // signers name String issuer = "KeyPairCost"; // subjects name - the same as we are self signed. String subject = "KeyPairCost"; java.util.Date date1 = new java.util.Date(); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(1024); //default SecureRandom KeyPair keypair = keyGen.genKeyPair(); PrivateKey privKey = keypair.getPrivate(); PublicKey pubKey = keypair.getPublic(); java.util.Date date2 = new java.util.Date(); long diff = date2.getTime()-date1.getTime(); System.out.println("Generate KeyPair takes " + diff + " msec"); // create the certificate - version 1 v1CertGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis())); v1CertGen.setIssuerDN(new X509Principal(issuer)); v1CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30)); // one month v1CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 30 * 1200 ))); // 10 years v1CertGen.setSubjectDN(new X509Principal(subject)); v1CertGen.setPublicKey(pubKey); v1CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption"); X509Certificate cert = v1CertGen.generate(privKey,"BC"); // now write it to key store KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(null, "changeit".toCharArray()); Certificate[] chain = new Certificate[1]; chain[0] = cert; ks.setKeyEntry("dualidp", privKey, "changeit".toCharArray(), chain); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ks.store(bOut, "changeit".toCharArray()); java.util.Date date3 = new java.util.Date(); diff = date3.getTime()-date2.getTime(); System.out.println("Store takes " + diff + " msec"); } public static void main(String[] args) { Security.addProvider(new BouncyCastleProvider()); System.out.println("---- test start ----"); try { generateKeyPairCost(); } catch (Exception e) { e.printStackTrace(); } System.out.println("---- test end ----"); } }