AES解密方法出错 [英] Error with AES decryption method

查看:224
本文介绍了AES解密方法出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有解密的真正问题,不知道如何解决这个java.crypto.BadPaddingException。我以前有一个类似的系统工作正常,现在我已经停止了最后一周。我读过很多stackoverflow线程,但是没有一个解决我的问题,除非我当然不明白。

I'm having real issues with decryption and don't know how to resolve this 'java.crypto.BadPaddingException'. I have had a similar previous system working just fine, now I've been halted for the last week. I have read many stackoverflow threads, but none really solve my issue...unless of course, I simply didn't understand it.

我的问题出现在登录方法它说: byte [] decryptpted = cipher.doFinal(p.getBytes());

My issue arises in the login method where it says: byte[] decrypted = cipher.doFinal(p.getBytes());

public void register() {
    // ENCRYPT PASSWORD
    try {
        String key = username; // 128bit key (16*8)
        String text = password;

        // CREATE KEY AND CIPHER
        Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES");

        // ENCRYPT THE TEXT
        cipher.init(Cipher.ENCRYPT_MODE, aesKey);
        byte[] encrypted = cipher.doFinal(text.getBytes());
        System.out.println("Encrypted: " + new String(encrypted));

        // SET VARIABLE FOR SAVING
        p = new String(new String(encrypted));
        System.out.println("p: " + new String(p));
        System.out.println("p: " + password);
    }
    catch (Exception e){
        e.printStackTrace();
    }

    // ENCRYPT QUESTION
    try {
        String key = username; // 128bit key (16*8)
        String text = question;

        // CREATE KEY AND CIPHER
        Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES");

        // ENCRYPT THE TEXT
        cipher.init(Cipher.ENCRYPT_MODE, aesKey);
        byte[] encrypted = cipher.doFinal(text.getBytes());
        System.out.println("Encrypted: " + new String(encrypted));

        // SET VARIABLE FOR SAVING
        q = new String(new String(encrypted));
        System.out.println("q: " + new String(q));
        System.out.println("q: " + question);
    }
    catch (Exception e){
        e.printStackTrace();
    }

    // ENCRYPT ANSWER
    try {
        String key = username; // 128bit key (16*8)
        String text = answer;

        // CREATE KEY AND CIPHER
        Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES");

        // ENCRYPT THE TEXT
        cipher.init(Cipher.ENCRYPT_MODE, aesKey);
        byte[] encrypted = cipher.doFinal(text.getBytes());
        System.out.println("Encrypted: " + new String(encrypted));

        // SET VARIABLE FOR SAVING
        an = new String(new String(encrypted));
        System.out.println("an: " + new String(an));
        System.out.println("an: " + answer);
    }
    catch (Exception e){
        e.printStackTrace();
    }



    // SAVE DATA IN LICENSE FILE
    try {
        File file = new File("C://Welcome/License.txt");
        file.getParentFile().mkdirs();
        FileWriter fw = new FileWriter(file);
        BufferedWriter bw = new BufferedWriter(fw);

        //bw.write(new String(u));
        //bw.newLine();
        bw.write(new String(p));
        bw.newLine();
        bw.write(new String(q));
        bw.newLine();
        bw.write(new String(an));
        bw.close();
    }
    catch(FileNotFoundException ex){
        ex.printStackTrace();
    }
    catch(IOException ex){
        ex.printStackTrace();
    }

    // CREATE A FOLDER FOR FILES
    try {
        File dir = new File("C://IronFortress/Files");
        dir.mkdir();
    }
    catch(Exception e){
        e.printStackTrace();
    }
}

public void login() {
    // LOAD PASSWORD, QUESTION AND ANSWER HASHES
    String fileName = "C:/Welcome/License.txt";
    String line0 = null;
    String line1 = null;
    String line2 = null;

    try {
        FileReader fr = new FileReader(fileName);
        BufferedReader br = new BufferedReader(fr);

        if((line0 = br.readLine()) != null){
            p = (line0);
        }
        if((line1 = br.readLine()) != null){
            q = (line1);
        }
        if((line2 = br.readLine()) != null){
            an = (line2);
        }

        br.close();
    }
    catch(FileNotFoundException e) {
        e.printStackTrace();
    }
    catch (IOException e) {
        e.printStackTrace();
    }



    // DECRYPT STORED PASSWORD
    try {
        String key = username; // 128bit key (16*8)
        String text = p;

        // CREATE KEY AND CIPHER
        Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES");

        // DECRYPT THE TEXT
        cipher.init(Cipher.DECRYPT_MODE, aesKey);
        byte[] decrypted = cipher.doFinal(p.getBytes());
        System.out.println("Decrypted Pass: " + new String(decrypted));

                // COMPARE VALUES
                if (password.equals(new String(decrypted))){
                //if (tf2.getText().equals(new String(decrypted))){
                    welcome.setVisible(true);
                    bg.setVisible(false);
                    l.setVisible(false);
                    tf1.setVisible(false);
                    tf2.setVisible(false);
                    b3.setVisible(false);
                    b4.setVisible(false);
                }
    }
    catch (Exception e){
        e.printStackTrace();
    }
}




javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
    at javax.crypto.Cipher.doFinal(Cipher.java:2087)
    at IronFortress.intro.login(intro.java:327)
    at IronFortress.intro.actionPerformed(intro.java:482)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)


推荐答案

主要问题是 new字符串(加密的)。密文由任意字节组成。其中一些字节是不可打印的。直接从具有默认系统编码的字节创建字符串将会静默地丢弃一些字节。所以你的密文将被破坏,明文无法恢复。

The main problem is new String(encrypted). Ciphertexts are made up of arbitrary bytes. Some of those bytes are unprintable. Creating a string directly from those bytes with the default system encoding will silently throw away some bytes. So your ciphertext will be broken and the plaintext cannot be recovered.

为了加密任意长度的明文,加密之前(自动)应用填充。当解密运行时,它将尝试删除先前应用的填充。如果密文以某种方式改变(取决于操作模式),则可以通过检查填充是否有效(它具有非常具体的格式)来检测该操作。如果填充无效并且无法删除,您将收到BadPaddingException。

In order to encrypt arbitrary length plaintexts a padding is (automatically) applied before encryption. When the decryption runs, it will try to remove the previously applied padding. If the ciphertext is altered in some way (depends on the mode of operation) it is possible to detect this manipulation by checking if the padding is valid (it has a very specific format). You'll get a BadPaddingException if the padding wasn't valid and couldn't have been removed.

如果要生成文本密文输出,则需要正确使用Base64或Hex对您的密文进行编码。然后解密之前你会解码它。

If you want to produce textual ciphertext output, then you need to properly encode your ciphertext for example with Base64 or Hex. Then you would decode it before decryption.

其他问题


  • Cipher.getInstance(AES)未完全限定。您需要使用完全限定的字符串来防止在更换系统时出现意外。例如 Cipher.getInstance(AES / CBC / PKCS5Padding)。您当前的密码字符串可能默认为ECB模式...

  • 不要使用ECB模式!随机使用CBC模式IV。 IV不必是秘密的,所以你可以把它添加到密文中。

  • 总是指定你使用的编码: new String(bytes, UTF-8) string.getBytes(UTF-8)。否则,您将无法在具有不同系统编码的另一个系统上解密您的密文。

  • new String(new String(encrypted)); / code>不会使它更多的字符串比 new String(加密)

  • 你不需要将您的密文编码为Base64或Hex。您可以继续使用 byte [] 并从FileWriter切换到FileOutputStream。

  • Cipher.getInstance("AES") is not fully qualified. You need to use a fully qualified string to prevent surprises when you change systems. For example Cipher.getInstance("AES/CBC/PKCS5Padding"). You current cipher string probably defaults to ECB mode...
  • Don't use ECB mode! Use CBC mode with a random IV. The IV doesn't have to be secret, so you can prepend it to the ciphertext.
  • Always specify the encoding that you use: new String(bytes, "UTF-8") and string.getBytes("UTF-8"). Otherwise, you won't be able to decrypt your ciphertexts on another system that has a different system encoding.
  • new String(new String(encrypted)); won't make it more of a string than new String(encrypted).
  • You don't need to encode your ciphertext into Base64 or Hex. You can continue using byte[] and switch from FileWriter to FileOutputStream.

这篇关于AES解密方法出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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