web-dev-qa-db-ja.com

java aes javax.crypto.BadPaddingException:指定された最後のブロックが適切にパディングされていません

public class AES {

    public String getEncrypt(String pass){
        String password = encrypt(pass);
        return password;
    }

    public String getDecrypt(String pass){
        String key = "AesSEcREtkeyABCD";
        byte[] passwordByte = decrypt(key,pass);
        String password = new String(passwordByte);
        return password;
    }

    private byte[] decrypt(String key, String encrypted) {
        try {
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(skeySpec.getEncoded(), "AES"));
            //getting error here
            byte[] original = cipher.doFinal(encrypted.getBytes());
            return original;
        } catch (IllegalBlockSizeException ex) {
            ex.printStackTrace();
        } catch (BadPaddingException ex) {
            ex.printStackTrace();
        } catch (InvalidKeyException ex) {
            ex.printStackTrace();
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        } catch (NoSuchPaddingException ex) {
            ex.printStackTrace();
        }
        return null;
    } 

    private String encrypt(String value) {
        try {
            byte[] raw = new byte[]{'A', 'e', 's', 'S', 'E', 'c', 'R', 'E', 't', 'k', 'e', 'y','A','B','C','D'};
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            byte[] encrypted = cipher.doFinal(value.getBytes());
            System.out.println("encrypted string:" + (new String(encrypted)));
            return new String(encrypted);
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        } catch (IllegalBlockSizeException ex) {
            ex.printStackTrace();       
        } catch (BadPaddingException ex) {
            ex.printStackTrace();
        } catch (InvalidKeyException ex) {
            ex.printStackTrace();
        } catch (NoSuchPaddingException ex) {
            ex.printStackTrace();
        }
        return null;
    }

**復号化するたびにnullポインタがあります。時々それは私に正しい解読されたパスワードを与えるが、時々それは私にヌルポインタを与える。ここで何が問題なのか推測できません**

7
Allen Arcenal

文字列とバイト配列を混在させています。それは必ずしも良いことではありません。少なくとも、バイトから文字への変換に使用している文字セットを指定してください。それでも100%安全ではありません。文字列を文字列として扱い、バイト配列をバイト配列として扱う方がよいでしょう。

それでも解決しない場合は、「不正なパディング」エラーを引き起こす可能性のあることがたくさんあります。基本的に、最後のブロックの終わりが予想されるパディングと一致しない原因となるものはすべて、エラーをスローします。考えられる原因には、パディング設定の誤り、キーの誤り、暗号文の破損などがあります。

問題を診断するために、復号化側をNoPaddingに設定します。これは何でも受け入れ、出力を調べることができます。

  • 完全なゴミ:キーまたは異なるモード設定にエラーがある可能性があります。

  • 最初のブロックのゴミ:キーエラーまたはIVエラーがある可能性があります。

  • 最後のブロックのゴミ:暗号文ファイルの終わりが壊れている可能性があります。

  • 最後にいくつかの奇妙なバイトがある正しい復号化:奇妙なバイトはパディングです。

それが本当にパディングだけである場合は、その種のパディングを期待するように復号化関数を設定します。それ以外の場合は、キー/ IV /暗号文がbyte-for-byte暗号化と復号化の両方で同じであることを確認してください。

診断後にパディングモードを設定するのはvitalです。 NoPaddingは安全ではありません。

8
rossum