private static byte[] decrypt(byte[] decoded, String dekInfo, char[] passwd) throws IOException, GeneralSecurityException { if (passwd == null) { throw new IOException("Password is null, but a password is required"); } StringTokenizer tknz = new StringTokenizer(dekInfo, ","); String algorithm = tknz.nextToken(); byte[] iv = Hex.decode(tknz.nextToken()); if (!CipherModule.isSupportedCipher(algorithm)) { throw new IOException("Unknown algorithm: " + algorithm); } String[] cipher = org.jruby.ext.openssl.Cipher.Algorithm.osslToJsse(algorithm); String realName = cipher[3]; int[] lengths = org.jruby.ext.openssl.Cipher.Algorithm.osslKeyIvLength(algorithm); int keyLen = lengths[0]; int ivLen = lengths[1]; if (iv.length != ivLen) { throw new IOException("Illegal IV length"); } byte[] salt = new byte[8]; System.arraycopy(iv, 0, salt, 0, 8); OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(passwd), salt); KeyParameter param = (KeyParameter) pGen.generateDerivedParameters(keyLen * 8); SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(param.getKey(), realName); Cipher c = Cipher.getInstance(realName); c.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); return c.doFinal(decoded); }
private static void writePemEncrypted( BufferedWriter out, String pemHeader, byte[] encoding, CipherSpec cipher, char[] passwd) throws IOException { Cipher c = cipher.getCipher(); byte[] iv = new byte[c.getBlockSize()]; random.nextBytes(iv); byte[] salt = new byte[8]; System.arraycopy(iv, 0, salt, 0, 8); OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(passwd), salt); KeyParameter param = (KeyParameter) pGen.generateDerivedParameters(cipher.getKeyLenInBits()); SecretKey secretKey = new SecretKeySpec( param.getKey(), org.jruby.ext.openssl.Cipher.Algorithm.getAlgorithmBase(c)); byte[] encData = null; try { c.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv)); encData = c.doFinal(encoding); } catch (GeneralSecurityException gse) { throw new IOException("exception using cipher: " + gse.toString()); } out.write(BEF_G + pemHeader + AFT); out.newLine(); out.write("Proc-Type: 4,ENCRYPTED"); out.newLine(); out.write("DEK-Info: " + cipher.getOsslName() + ","); writeHexEncoded(out, iv); out.newLine(); out.newLine(); writeEncoded(out, encData); out.write(BEF_E + pemHeader + AFT); out.flush(); }