/** c: PEM_read_PrivateKey + PEM_read_bio_PrivateKey CAUTION: KeyPair#getPublic() may be null. */ public static KeyPair readPrivateKey(Reader in, char[] password) throws IOException { BufferedReader _in = makeBuffered(in); String line; while ((line = _in.readLine()) != null) { if (line.indexOf(BEF_G + PEM_STRING_RSA) != -1) { try { return readKeyPair(_in, password, "RSA", BEF_E + PEM_STRING_RSA); } catch (Exception e) { throw new IOException("problem creating RSA private key: " + e.toString()); } } else if (line.indexOf(BEF_G + PEM_STRING_DSA) != -1) { try { return readKeyPair(_in, password, "DSA", BEF_E + PEM_STRING_DSA); } catch (Exception e) { throw new IOException("problem creating DSA private key: " + e.toString()); } } else if (line.indexOf(BEF_G + PEM_STRING_ECPRIVATEKEY) != -1) { throw new IOException("EC private key not supported"); } else if (line.indexOf(BEF_G + PEM_STRING_PKCS8INF) != -1) { try { byte[] bytes = readBytes(_in, BEF_E + PEM_STRING_PKCS8INF); PrivateKeyInfo info = new PrivateKeyInfo((ASN1Sequence) new ASN1InputStream(bytes).readObject()); String type = getPrivateKeyTypeFromObjectId(info.getAlgorithmId().getObjectId()); return org.jruby.ext.openssl.impl.PKey.readPrivateKey( info.getPrivateKey().getDEREncoded(), type); } catch (Exception e) { throw new IOException("problem creating private key: " + e.toString()); } } else if (line.indexOf(BEF_G + PEM_STRING_PKCS8) != -1) { try { byte[] bytes = readBytes(_in, BEF_E + PEM_STRING_PKCS8); org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo( (ASN1Sequence) new ASN1InputStream(bytes).readObject()); AlgorithmIdentifier algId = eIn.getEncryptionAlgorithm(); PrivateKey privKey; if (algId.getAlgorithm().toString().equals("1.2.840.113549.1.5.13")) { // PBES2 privKey = derivePrivateKeyPBES2(eIn, algId, password); } else { privKey = derivePrivateKeyPBES1(eIn, algId, password); } return new KeyPair(null, privKey); } catch (Exception e) { throw new IOException("problem creating private key: " + e.toString()); } } } return null; }
private static PrivateKey derivePrivateKeyPBES2( org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn, AlgorithmIdentifier algId, char[] password) throws GeneralSecurityException, InvalidCipherTextException { PBES2Parameters pbeParams = new PBES2Parameters((ASN1Sequence) algId.getParameters()); CipherParameters cipherParams = extractPBES2CipherParams(password, pbeParams); EncryptionScheme scheme = pbeParams.getEncryptionScheme(); BufferedBlockCipher cipher; if (scheme.getAlgorithm().equals(PKCSObjectIdentifiers.RC2_CBC)) { RC2CBCParameter rc2Params = new RC2CBCParameter((ASN1Sequence) scheme.getObject()); byte[] iv = rc2Params.getIV(); CipherParameters param = new ParametersWithIV(cipherParams, iv); cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RC2Engine())); cipher.init(false, param); } else { byte[] iv = ((ASN1OctetString) scheme.getObject()).getOctets(); CipherParameters param = new ParametersWithIV(cipherParams, iv); cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine())); cipher.init(false, param); } byte[] data = eIn.getEncryptedData(); byte[] out = new byte[cipher.getOutputSize(data.length)]; int len = cipher.processBytes(data, 0, data.length, out, 0); len += cipher.doFinal(out, len); byte[] pkcs8 = new byte[len]; System.arraycopy(out, 0, pkcs8, 0, len); KeyFactory fact = KeyFactory.getInstance("RSA"); // It seems to work for both RSA and DSA. return fact.generatePrivate(new PKCS8EncodedKeySpec(pkcs8)); }
private AlgorithmParameters getParameters() throws NoSuchAlgorithmException { AlgorithmParameters ap = AlgorithmParameters.getInstance(this.getAlgName()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); try { dOut.writeObject(infoObj.getEncryptionAlgorithm().getParameters()); dOut.close(); ap.init(bOut.toByteArray()); } catch (IOException e) { throw new NoSuchAlgorithmException("unable to parse parameters"); } return ap; }
private static PrivateKey derivePrivateKeyPBES1( org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn, AlgorithmIdentifier algId, char[] password) throws GeneralSecurityException { PKCS12PBEParams pkcs12Params = new PKCS12PBEParams((ASN1Sequence) algId.getParameters()); PBEParameterSpec pbeParams = new PBEParameterSpec(pkcs12Params.getIV(), pkcs12Params.getIterations().intValue()); String algorithm = ASN1Registry.o2a(algId.getAlgorithm()); algorithm = (algorithm.split("-"))[0]; Cipher cipher = OpenSSLReal.getCipherBC(algorithm); // need to use BC for PBEParameterSpec. SecretKeyFactory fact = OpenSSLReal.getSecretKeyFactoryBC(algorithm); // need to use BC for PKCS12PBEParams. SecretKey key = fact.generateSecret(new PBEKeySpec(password)); cipher.init(Cipher.UNWRAP_MODE, key, pbeParams); // wrappedKeyAlgorithm is unknown ("") return (PrivateKey) cipher.unwrap(eIn.getEncryptedData(), "", Cipher.PRIVATE_KEY); }
/** * Returns a copy of the encrypted data. * * @returns a copy of the encrypted data. */ public byte[] getEncryptedData() { return infoObj.getEncryptedData(); }
/** * Returns the encryption algorithm. * * @returns the algorithm name. */ public String getAlgName() { return infoObj.getEncryptionAlgorithm().getObjectId().getId(); }