/** * Returns the key associated with the given alias, using the given password to recover it. * * @param alias the alias name * @param password the password for recovering the key. This password is used internally as the * key is exported in a PKCS12 format. * @return the requested key, or null if the given alias does not exist or does not identify a * <i>key entry</i>. * @exception NoSuchAlgorithmException if the algorithm for recovering the key cannot be found * @exception UnrecoverableKeyException if the key cannot be recovered (e.g., the given password * is wrong). */ public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { permissionCheck(); // An empty password is rejected by MacOS API, no private key data // is exported. If no password is passed (as is the case when // this implementation is used as browser keystore in various // deployment scenarios like Webstart, JFX and applets), create // a dummy password so MacOS API is happy. if (password == null || password.length == 0) { // Must not be a char array with only a 0, as this is an empty // string. if (random == null) { random = new SecureRandom(); } password = Long.toString(random.nextLong()).toCharArray(); } Object entry = entries.get(alias.toLowerCase()); if (entry == null || !(entry instanceof KeyEntry)) { return null; } // This call gives us a PKCS12 bag, with the key inside it. byte[] exportedKeyInfo = _getEncodedKeyData(((KeyEntry) entry).keyRef, password); if (exportedKeyInfo == null) { return null; } PrivateKey returnValue = null; try { byte[] pkcs8KeyData = fetchPrivateKeyFromBag(exportedKeyInfo); byte[] encryptedKey; AlgorithmParameters algParams; ObjectIdentifier algOid; try { // get the encrypted private key EncryptedPrivateKeyInfo encrInfo = new EncryptedPrivateKeyInfo(pkcs8KeyData); encryptedKey = encrInfo.getEncryptedData(); // parse Algorithm parameters DerValue val = new DerValue(encrInfo.getAlgorithm().encode()); DerInputStream in = val.toDerInputStream(); algOid = in.getOID(); algParams = parseAlgParameters(in); } catch (IOException ioe) { UnrecoverableKeyException uke = new UnrecoverableKeyException( "Private key not stored as " + "PKCS#8 EncryptedPrivateKeyInfo: " + ioe); uke.initCause(ioe); throw uke; } // Use JCE to decrypt the data using the supplied password. SecretKey skey = getPBEKey(password); Cipher cipher = Cipher.getInstance(algOid.toString()); cipher.init(Cipher.DECRYPT_MODE, skey, algParams); byte[] decryptedPrivateKey = cipher.doFinal(encryptedKey); PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(decryptedPrivateKey); // Parse the key algorithm and then use a JCA key factory to create the private key. DerValue val = new DerValue(decryptedPrivateKey); DerInputStream in = val.toDerInputStream(); // Ignore this -- version should be 0. int i = in.getInteger(); // Get the Algorithm ID next DerValue[] value = in.getSequence(2); AlgorithmId algId = new AlgorithmId(value[0].getOID()); String algName = algId.getName(); // Get a key factory for this algorithm. It's likely to be 'RSA'. KeyFactory kfac = KeyFactory.getInstance(algName); returnValue = kfac.generatePrivate(kspec); } catch (Exception e) { UnrecoverableKeyException uke = new UnrecoverableKeyException("Get Key failed: " + e.getMessage()); uke.initCause(e); throw uke; } return returnValue; }
// Program demonstrating how to create a random key and then search for the key value. public static void main(String[] args) { if (2 != args.length) { System.out.println("Usage: java SealedDES #KEYSIZE #NUMTHREADS"); return; } // create object to printf to the console PrintStream p = new PrintStream(System.out); // Get the argument long keybits = Long.parseLong(args[0]); int numThreads = Integer.parseInt(args[1]); long maxkey = ~(0L); maxkey = maxkey >>> (64 - keybits); // Create a simple cipher SealedDES enccipher = new SealedDES(); // Get a number between 0 and 2^64 - 1 Random generator = new Random(); long key = generator.nextLong(); // Mask off the high bits so we get a short key key = key & maxkey; // Set up a key enccipher.setKey(key); // Generate a sample string String plainstr = "Johns Hopkins afraid of the big bad wolf?"; long runstart; runstart = System.currentTimeMillis(); Thread[] threads = new Thread[numThreads]; Runnable[] decrypters = new Runnable[numThreads]; long keySpaceSize = 0; if (numThreads > 0) { keySpaceSize = maxkey / numThreads; } for (int i = 0; i < numThreads; i++) { SealedObject sldObj = enccipher.encrypt(plainstr); decrypters[i] = new DecryptionRunner( i, new SealedDES(), keySpaceSize * i, keySpaceSize * (i + 1), sldObj); threads[i] = new Thread(decrypters[i]); threads[i].start(); } for (int i = 0; i < numThreads; i++) { try { threads[i].join(); } catch (InterruptedException e) { System.out.println("Join on thread [" + i + "] interrupted"); break; } } // Output search time long elapsed = System.currentTimeMillis() - runstart; long keys = maxkey + 1; System.out.println("Completed search of " + keys + " keys at " + elapsed + " milliseconds."); }