使用Java进行AES加密和解密

时间:2013-12-27 06:35:38

标签: java encryption cryptography aes

这是我正在做的事情,看起来有点笨拙,但任何帮助都对这个问题表示赞赏。我得到BadPaddingException。阅读几乎所有相关主题,但没有找到合适的解决方案。我是加密解密编程的新手,需要在我的一个Java应用程序中实现它。

谢谢.. 这就是代码的外观......

public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    // TODO Auto-generated method stub
            String FileName="encryptedtext.txt";
            String FileName2="decryptedtext.txt";
            String pad="0"; 

            KeyGenerator KeyGen=KeyGenerator.getInstance("AES");
            KeyGen.init(128);

            SecretKey SecKey=KeyGen.generateKey();

            Cipher AesCipher=Cipher.getInstance("AES");
            AesCipher.init(Cipher.ENCRYPT_MODE,SecKey);

            byte[] byteText="My name is yogesh".getBytes();
            byte[] byteCipherText=AesCipher.doFinal(byteText);
            String cipherText = null;

            try {
                FileWriter fw=new FileWriter(FileName);
                BufferedWriter bw=new BufferedWriter(fw);
                bw.write(byteCipherText.toString());
                bw.close();
            }catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            try {
                FileReader fr=new FileReader(FileName);
                BufferedReader br=new BufferedReader(fr);
                cipherText=br.readLine();
                br.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            AesCipher.init(Cipher.DECRYPT_MODE,SecKey);
            while(((cipherText.getBytes().length)%16)!=0)
            {
                cipherText=cipherText+pad;


            }

            byte[] bytePlainText=AesCipher.doFinal(cipherText.getBytes());
            FileWriter fw1;
            try {
                fw1 = new FileWriter(FileName2);
                BufferedWriter bw1=new BufferedWriter(fw1);
                bw1.write(bytePlainText.toString());
                bw1.close();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }






}

2 个答案:

答案 0 :(得分:15)

在这里,您必须了解的是密文可能包含不可打印的字符。因此,当您使用readLine()时,它可能不会为您提供文件中的所有字节。

此外,byteCipherText.toString()并未提供您认为会得到的内容。在java中,toString()方法不提供数组内容的字符串表示。

无需为加密文本添加填充。它已经填充了。

import java.nio.file.Files;
import java.nio.file.Paths;
import javax.crypto.*;

public class Main {

    public static void main(String[] args) throws Exception {
        String fileName = "encryptedtext.txt";
        String fileName2 = "decryptedtext.txt";

        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128);

        SecretKey secKey = keyGen.generateKey();

        Cipher aesCipher = Cipher.getInstance("AES");


        byte[] byteText = "Your Plain Text Here".getBytes();

        aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
        byte[] byteCipherText = aesCipher.doFinal(byteText);
        Files.write(Paths.get(fileName), byteCipherText);


        byte[] cipherText = Files.readAllBytes(Paths.get(fileName));

        aesCipher.init(Cipher.DECRYPT_MODE, secKey);
        byte[] bytePlainText = aesCipher.doFinal(cipherText);
        Files.write(Paths.get(fileName2), bytePlainText);
    }
}

答案 1 :(得分:9)

您需要定义在创建Cipher实例时使用的填充算法。我个人使用PKCS5

所以你应该改变:

Cipher AesCipher=Cipher.getInstance("AES");

为:

Cipher AesCipher=Cipher.getInstance("AES/CBC/PKCS5Padding");

CBC代表Cipher-block chaining

CBC要求传递IV。因此,您希望生成随机IV并将其传递给init方法:

byte[] iv = new byte[16];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
AesCipher.init(Cipher.ENCRYPT_MODE, SecKey, ivParameterSpec);

注意:在代码中避免使用魔法数字/字符串是一种很好的做法。我建议将Cipher#getInstance中的参数传递提取到常量。