使用Java进行AES加密和解密

Yog*_*h D 8 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();
            }






}
Run Code Online (Sandbox Code Playgroud)

bga*_*ath 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这样的加密并不安全,因为它不使用IV.在生产环境中使用此代码将是非常愚蠢的**. (9认同)
  • @Allan5 在非常特殊的情况下不需要 IV。例如,如果密钥不断变化,并且您加密的数据块大小小于块大小(AES 为 128 位)。否则使用静脉注射。或者只是一直使用一个。 (2认同)

Ler*_*eri 9

您需要定义在创建实例时使用的填充算法Cipher.我亲自用PKCS5.

所以你应该改变:

Cipher AesCipher=Cipher.getInstance("AES");
Run Code Online (Sandbox Code Playgroud)

至:

Cipher AesCipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
Run Code Online (Sandbox Code Playgroud)

CBC代表密码块链接.

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);
Run Code Online (Sandbox Code Playgroud)

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