我有一个刻有DES/ECB/PKCS5Padding的私钥文件(由一个 secret 短语生成的56位DES key ),我想对其解密。
我不知道为什么,但是每次尝试解密时,我的密码类的doFinal方法都会抛出此错误:



这是我的代码:

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 而不是KeyGenerator。当然,您将需要8字节的 key 数据。在您的情况下,检索此错误的唯一方法是先找到SecureRandom算法/实现,然后重新计算 key 。

现在,任何密文都将使用任何 key 解密。 DES ECB仅提供(某种形式) secret 性,而不提供完整性。问题在于它将解密为垃圾。现在,如果您尝试从垃圾中删除填充,则可能会出现填充错误。

如果您“幸运”-大约256次-您将获得结果。当解密的块以010202结尾时,就会发生这种情况,这是有效的填充。结果当然也将是垃圾,但结果不会以BadPaddingException结尾。在您的情况下,SecureRandom实例可能会一遍又一遍地返回相同的不正确值,因此这可能永远不会发生。

将来,请使用PBKDF2并为其提供编码后的密码。清楚地注意所使用的字符编码,Java SE使用char数组的最低8位。切勿使用String.getBytes(),因为默认编码在系统之间可能会有所不同。

09-07 15:13