我有一个用 DES/ECB/PKCS5Padding 加密的私钥文件(由秘密短语生成的 56 位 DES 密钥),我想解密它。
我不知道为什么,但每次我尝试解密时,我的密码类的方法 doFinal 都会抛出此错误:
javax.crypto.BadPaddingException:给定的最终块不正确
填充于 com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) 在
com.sun.crypto.provider.DESCipher.engineDoFinal(DashoA13*..) 在
javax.crypto.Cipher.doFinal(DashoA13*..) 在...
这是我的代码:
public static PrivateKey readPrivateKeyFromFile(File file, String chaveSecreta) {
try {
SecureRandom r = new SecureRandom(chaveSecreta.getBytes());
KeyGenerator keyGen = KeyGenerator.getInstance("DES");
keyGen.init(56, r);
Key key = keyGen.generateKey();
byte[] privateKeyBytes = decryptPKFile(file, key);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = null;
try {
privateKey = keyFactory.generatePrivate(privateKeySpec);
} catch (InvalidKeySpecException e) {
JOptionPane.showMessageDialog(null, "Erro 01, tente mais tarde");
}
return privateKey;
} catch (NoSuchAlgorithmException e) {
JOptionPane.showMessageDialog(null, "Erro 02, tente mais tarde");
}
return null;
}
public static byte[] decryptPKFile(File file, Key key){
try{
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
byte[] cipherText = readBytes(file);
cipher.init(Cipher.DECRYPT_MODE, key);
System.out.println(cipher);
System.out.println(cipherText);
byte[] text = cipher.doFinal(cipherText);
return text;
}catch(Exception e){
e.printStackTrace();
return null;
}
}
public static byte[] readBytes(File file) {
try {
FileInputStream fs = new FileInputStream(file);
byte content[] = new byte[(int) file.length()];
fs.read(content);
return content;
} catch (FileNotFoundException e) {
System.out.println("Arquivo não encontrado!");
e.printStackTrace();
} catch (IOException ioe) {
System.out.println("Erro ao ler arquivo!");
ioe.printStackTrace();
}
return null;
}
有什么建议么?
您正在尝试使用使用特定种子创建的随机数生成器来解密密文。但是,您没有指定算法,并且算法也可能在内部发生变化。 Android 甚至会为某些版本生成完全随机的值。
你需要使用一个SecretKeyFactory http://docs.oracle.com/javase/7/docs/api/javax/crypto/SecretKeyFactory.html not a KeyGenerator
。当然,您还需要 8 字节的密钥数据。在您的情况下检索此信息的唯一方法是找到SecureRandom
之前的算法/实现并重新计算密钥。
现在任何密文都可以用任何密钥解密。 DES ECB 仅提供(某种)机密性,而不提供完整性。问题是它会解密成垃圾。现在,如果您尝试从垃圾中删除填充,您可能会收到填充错误。
如果您“幸运”——大约 256 次中只有一次——您就会得到结果。当解密的块以以下结尾时会发生这种情况01
or 0202
,这是有效的填充。当然,结果也会是垃圾,但它不会以BadPaddingException
。在你的情况下SecureRandom
实例是likely一遍又一遍地返回相同的错误值,所以这可能永远不会发生。
将来,请使用 PBKDF2 并为其提供编码后的密码。清楚地注意所使用的字符编码,Java SE 使用 char 数组的最低 8 位。从来没有使用过String.getBytes()
因为系统之间的默认编码可能有所不同。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)