BadPaddingException:给定最终块未正确填充 [英] BadPaddingException: Given final block not properly padded

查看:153
本文介绍了BadPaddingException:给定最终块未正确填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个私有密钥文件被加密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 * ..)at
com.sun.crypto.provider.DESCipher.engineDoFinal(DashoA13 * ..)at
javax.crypto.Cipher.doFinal(DashoA13 * ..)at。


这是我的代码:

  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);
}
返回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);
返回文本;
} catch(Exception e){
e.printStackTrace();
返回null;
}
}

public static byte [] readBytes(File file){
try {
FileInputStream fs = new FileInputStream(file);
byte content [] = new byte [(int)file.length()];
fs.read(content);
返回内容;
} catch(FileNotFoundException e){
System.out.println(Arquivonãoencontrado!);
e.printStackTrace();
} catch(IOException ioe){
System.out.println(Erro ao ler arquivo!);
ioe.printStackTrace();
}
返回null;
}

任何syggestions?

解决方案

您正在尝试使用特定种子创建的随机数生成器解密密文。但是,您不指定算法,并且算法也可能内部改变。 Android甚至可以为某些版本产生完全随机的值。



您需要使用 SecretKeyFactory 不是 KeyGenerator 。而您当然需要8个字节的密钥数据。在你的情况下检索这个的唯一方法是在之前找到 SecureRandom 算法/实现,然后重新计算密钥。



现在任何密文都会用任何密钥解密。 DES ECB仅提供(某种)机密性,而不是完整性。问题是它会解密成垃圾。现在,如果你尝试从垃圾中删除填充,你可能会收到一个填充错误。



如果你幸运 - 一次在大约256次 - 你会得到结果。当解密的块以 01 0202 结束时,这是有效的填充。结果当然也是垃圾,但不会以$ code> BadPaddingException 结束。在你的情况下, SecureRandom 实例可能可以反复返回相同的错误值,所以这可能永远不会发生。 b
$ b

将来,请使用PBKDF2并给它编码密码。清楚地注意使用的字符编码,Java SE使用char数组的最低8位。从来没有使用 String.getBytes(),因为系统之间的默认编码可能不同。


I have a private key file encripted with DES/ECB/PKCS5Padding (56 bit DES key generated by a secret phrase) and I want to decrypt it. I don't know why, but everytime I try to decript, the method doFinal of my cipher class is throwing this error:

javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) at com.sun.crypto.provider.DESCipher.engineDoFinal(DashoA13*..) at javax.crypto.Cipher.doFinal(DashoA13*..) at...

Here is my code:

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;
}

Any syggestions?

解决方案

You're trying to decrypt ciphertext with a random number generator created using a specific seed. However, you don't specify the algorithm, and the algorithm may change internally as well. Android is even known to generate a fully random value instead for some versions.

You need to use a SecretKeyFactory not a KeyGenerator. And you will of course need the 8-byte key data. The only way to retrieve this in your case is to find the SecureRandom algorithm/implementation before and re-calculate the key.

Now any ciphertext will decrypt with any key. DES ECB only provides (some sort of) confidentiality, not integrity. The problem is that it will decrypt into garbage. Now if you try to remove the padding from garbage you will likely get a padding error.

If you're "lucky" - once in about 256 times - you will get a result. This happens when the decrypted block ends with 01 or 0202, that's valid padding. The result will - of course - be garbage as well, but it will not end with a BadPaddingException. In your case the SecureRandom instance is likely to return the same incorrect value over and over though, so this may never happen.

In the future, please use PBKDF2 and feed it the encoded password. Clearly note the character encoding used, Java SE uses the lowest 8 bits of the char array. Never ever use String.getBytes() as the default encoding may differ between systems.

这篇关于BadPaddingException:给定最终块未正确填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆