解密使用OpenSSL生成的“der”文件时出现exception:使用填充密码解密时,输入长度必须是8的倍数

首先,我使用OpenSSL生成一个私有RSA密钥文件,然后将其转换为加密的“der”文件:

$ openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key.pem -out private_key.der 

接下来我尝试使用以下代码从Java解密此文件(在此阶段我已经使用位于此post底部的代码将文件读入byte[] key数组):

 public static byte[] decryptPrivateKey(byte[] key) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { PBEKeySpec passKeySpec = new PBEKeySpec("p".toCharArray()); //my password EncryptedPrivateKeyInfo encryptedKey = new EncryptedPrivateKeyInfo(key); System.out.println(encryptedKey.getAlgName()); //PBEWithMD5AndDES System.out.println("key length: " + key.length); //key length: 677 SecretKeyFactory keyFac = SecretKeyFactory.getInstance(encryptedKey.getAlgName()); SecretKey passKey = keyFac.generateSecret(passKeySpec); // Create PBE Cipher Cipher pbeCipher = Cipher.getInstance(encryptedKey.getAlgName()); // Initialize PBE Cipher with key and parameters pbeCipher.init(Cipher.DECRYPT_MODE, passKey, encryptedKey.getAlgParameters()); // Decrypt the private key(throws the exception) return pbeCipher.doFinal(key); } 

我在上面的return语句中得到以下堆栈跟踪:

 Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750) at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676) at com.sun.crypto.provider.PBECipherCore.doFinal(PBECipherCore.java:422) at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineDoFinal(PBEWithMD5AndDESCipher.java:316) at javax.crypto.Cipher.doFinal(Cipher.java:2087) at roland.test.crypto.Test.decryptPrivateKey(Test.java:96) at roland.test.crypto.Test.getPrivateKey(Test.java:74) at roland.test.crypto.Test.test(Test.java:58) at roland.test.crypto.Test.main(Test.java:30) 

密钥作为字节数组从“der”文件中读取:

 public static PrivateKey getPrivateKey() throws Exception { byte[] key = null; try(final InputStream resourceStream = getMyClass().getResourceAsStream("private_key.der")) { //$NON-NLS-1$\r key = ByteStreams.toByteArray(resourceStream); } catch (IOException e) { e.printStackTrace(); } key = decryptPrivateKey(key); } 

解决方案是:

 return pbeCipher.doFinal(encryptedKey.getEncryptedData());