java - 错误填充异常 :pad block corrupt when calling dofinal

标签 java encryption-symmetric

我正在研究加密和解密。我对密码学非常陌生,在使用充气城堡时遇到垫 block 损坏异常

这是我的加密/解密代码。

私有(private)AESFastEngine引擎;

private BufferedBlockCipher cipher;

private final KeyParameter key=setEncryptionKey("testinggtestingg");

public  KeyParameter setEncryptionKey(String keyText) {
    // adding in spaces to force a proper key
    keyText += "                ";

    // cutting off at 128 bits (16 characters)
    keyText = keyText.substring(0, 16);

    byte[] keyBytes = keyText.getBytes();
    //key = new KeyParameter(keyBytes);
    engine = new AESFastEngine();
    cipher = new PaddedBufferedBlockCipher(engine);
    return new KeyParameter(keyBytes);

}

public String encryptString(String plainText) {

    try {
        byte[] plainArray = plainText.getBytes();
        cipher.init(true, key);
        byte[] cipherBytes = new byte[cipher
                .getOutputSize(plainArray.length)];
        int cipherLength = cipher.processBytes(plainArray, 0,
                plainArray.length, cipherBytes, 0);
        cipher.doFinal(cipherBytes, cipherLength);

        return (new String(cipherBytes));
    } catch (DataLengthException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (InvalidCipherTextException e) {
        e.printStackTrace();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    // else
    return null;
}

public String decryptString(String encryptedText) {
    try {
        byte[] cipherBytes = encryptedText.getBytes();
        cipher.init(false, key);
                byte[] decryptedBytes = new byte[cipher
                .getOutputSize(cipherBytes.length)];
        int decryptedLength = cipher.processBytes(cipherBytes, 0,
                cipherBytes.length, decryptedBytes, 0);
        cipher.doFinal(decryptedBytes,decryptedLength);
        String decryptedString = new String(decryptedBytes);

        // crop accordingly
        int index = decryptedString.indexOf("\u0000");
        if (index >= 0) {
            decryptedString = decryptedString.substring(0, index);
        }
        return decryptedString;
    } catch (DataLengthException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (InvalidCipherTextException e) {
        e.printStackTrace();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    // else
    return null;
} 

最佳答案

您所需要的只是精确的字符集。给你:

import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;

public class Main
{
    private BufferedBlockCipher cipher;
    private final KeyParameter key = setEncryptionKey("testinggtestingg");
    private static final String CHARSET = "ISO-8859-1";

    public static void main(String[] argv)
    {
        Main main = new Main();

        String plain = "trallalla";
        System.out.println("initial : " + plain);

        String encrypted = main.encryptString(plain);
        System.out.println("after encryption : " + encrypted);

        String decrypted = main.decryptString(encrypted);
        System.out.println("after decryption : " + decrypted);
    }

    public KeyParameter setEncryptionKey(String keyText)
    {
        // adding in spaces to force a proper key
        keyText += "                ";

        // cutting off at 128 bits (16 characters)
        keyText = keyText.substring(0, 16);

        byte[] keyBytes = keyText.getBytes();
        // key = new KeyParameter(keyBytes);
        AESFastEngine engine = new AESFastEngine();
        cipher = new PaddedBufferedBlockCipher(engine);
        return new KeyParameter(keyBytes);

    }

    public String encryptString(String plainText)
    {
        try
        {
            byte[] plainArray = plainText.getBytes();
            cipher.init(true, key);
            byte[] cipherBytes = new byte[cipher.getOutputSize(plainArray.length)];
            int cipherLength = cipher.processBytes(plainArray, 0, plainArray.length, cipherBytes, 0);
            cipher.doFinal(cipherBytes, cipherLength);

            return (new String(cipherBytes, CHARSET));
        }
        catch (DataLengthException e)
        {
            e.printStackTrace();
        }
        catch (IllegalArgumentException e)
        {
            e.printStackTrace();
        }
        catch (IllegalStateException e)
        {
            e.printStackTrace();
        }
        catch (InvalidCipherTextException e)
        {
            e.printStackTrace();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        // else
        return null;
    }

    public String decryptString(String encryptedText)
    {
        try
        {
            byte[] cipherBytes = encryptedText.getBytes(CHARSET);
            cipher.init(false, key);
            byte[] decryptedBytes = new byte[cipher.getOutputSize(cipherBytes.length)];
            int decryptedLength = cipher.processBytes(cipherBytes, 0, cipherBytes.length, decryptedBytes, 0);
            cipher.doFinal(decryptedBytes, decryptedLength);
            String decryptedString = new String(decryptedBytes);

            // crop accordingly
            int index = decryptedString.indexOf("\u0000");
            if (index >= 0)
            {
                decryptedString = decryptedString.substring(0, index);
            }
            return decryptedString;
        }
        catch (DataLengthException e)
        {
            e.printStackTrace();
        }
        catch (IllegalArgumentException e)
        {
            e.printStackTrace();
        }
        catch (IllegalStateException e)
        {
            e.printStackTrace();
        }
        catch (InvalidCipherTextException e)
        {
            e.printStackTrace();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        // else
        return null;
    }
}

但是你为什么要使用这个外部库?这是我使用的代码,不需要任何外部库:

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.*;
import javax.crypto.spec.*;


public class Encryption 
{
    private static final String ALGORITHME = "Blowfish";
    private static final String TRANSFORMATION = "Blowfish/ECB/PKCS5Padding";
    private static final String SECRET = "kjkdfjslm";
    private static final String CHARSET = "ISO-8859-1";


    public static void main(String[] argv) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException
    {
        Encryption main = new Encryption();

        String plain = "trallalla";
        System.out.println("initial : " + plain);

        String encrypted = main.encrypt(plain);
        System.out.println("after encryption : " + encrypted);

        String decrypted = main.decrypt(encrypted);
        System.out.println("after decryption : " + decrypted);
    }

    public String encrypt(String plaintext) 
    throws NoSuchAlgorithmException, 
    NoSuchPaddingException, 
    InvalidKeyException, 
    UnsupportedEncodingException, 
    IllegalBlockSizeException, 
    BadPaddingException
    {

            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(SECRET.getBytes(CHARSET), ALGORITHME));
            return new String(cipher.doFinal(plaintext.getBytes()), CHARSET);    
    }

    public String decrypt(String ciphertext) 
    throws NoSuchAlgorithmException, 
    NoSuchPaddingException, 
    InvalidKeyException, 
    UnsupportedEncodingException, 
    IllegalBlockSizeException, 
    BadPaddingException 
    {
      Cipher cipher = Cipher.getInstance(TRANSFORMATION);
      cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(SECRET.getBytes(), ALGORITHME));
      return new String(cipher.doFinal(ciphertext.getBytes(CHARSET)), CHARSET);
    }
}

关于java - 错误填充异常 :pad block corrupt when calling dofinal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14397672/

相关文章:

java - 尝试在空对象引用上调用虚拟方法 'android.content.pm.PackageManager android.content.Context.getPackageManager()'

java - 在 Java 和 golang 中使用 AES 时获得不同的结果(密文)

c# - 使用 DPAPI 时安全地存储可选的熵

c# - 从 SQL Server 2008 R2 解密数据

aes - WM-Bus扩展层解码

java - 使用 JButtons 编码数字用户输入的最佳方法?

java - 将 servlet 链接到 jsp。

java - 如何使用 Eclipse 安装 org.apache.commons.cli

Java在构造函数中初始化一个int数组

encryption - TLS 握手 - 对称方案