2

まず、フォーラムのすべてのエントリを確認しましたが、まだ問題の解決策が見つかりません。DES でテキストをエンコードおよびデコードするのにかかる時間を測定し、他のアルゴリズムと比較する必要があります。

コードを実行すると、次のエラーが表示されます: BadPaddingException: パッド ブロックが壊れています。デバッグすると、コードは次の行で失敗します。

  バイト [] 平文 = cipher.doFinal (cipherBytes);

クラス Base64 を使用して文字列をエンコード/デコードします <--> byte[]

何か案が?

ありがとう

private static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";
private static int KEY_LENGTH = 64;

 public static SecretKey deriveKeyDES() {
        try {
            long start = System.currentTimeMillis();

            KeyGenerator kgen = KeyGenerator.getInstance("DES");
            kgen.init(KEY_LENGTH);
            SecretKey result = kgen.generateKey();

            long elapsed = System.currentTimeMillis() - start;
            return result;

        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        } 
    }


    public static String encrypt(String plaintext, SecretKey key) {
        try {

            long start = System.currentTimeMillis();
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding")

            cipher.init(Cipher.ENCRYPT_MODE, key);

            byte[] cipherText = cipher.doFinal(plaintext.getBytes("UTF-8"));

            long elapsed = System.currentTimeMillis() - start;

            return toBase64(cipherText);

        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static String toBase64(byte[] bytes) {
        return Base64.encodeToString(bytes, Base64.NO_WRAP).trim();
    }


    public static String decrypt(String ciphertext, SecretKey key) {
        try {
            byte[] cipherBytes = fromBase64(ciphertext);

                long start = System.currentTimeMillis();
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

            cipher.init(Cipher.DECRYPT_MODE, key);
            cipher.update(cipherBytes);

             // This is where I get exception
            byte[] plaintext = cipher.doFinal(cipherBytes);

            String plainrStr = new String(plaintext, "UTF-8").trim();
            long elapsed = System.currentTimeMillis() - start;

            return plainrStr;
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] fromBase64(String base64) {
        return Base64.decode(base64, Base64.NO_WRAP);
    }
4

3 に答える 3

1

パディング例外は、最後の暗号テキスト ブロックが有効なプレーン テキストに計算されない場合に発生します。これは、最後の暗号文ブロックが破損しているか、キーが正しくない場合に発生します。CBC モードの場合、最後から 2 番目の暗号文が変更された場合にも発生します (ただし、ECB モードの暗号化を使用しています)。

あなたの場合、deriveKeyDES()は常にランダムなキーを生成しています。セキュリティ メソッドへの実際の呼び出しは得られませんでしたが、暗号化と復号化に別のキーを使用していると思います。その場合、結果のプレーン テキストに有効なパディング バイトが含まれていない可能性が非常に高くなります。

Rasmus の回答は確かにコードのエラーを示しており、タイミングを台無しにしてプレーンテキストを 2 回返しますが、BadPaddingException.

于 2012-08-25T11:08:05.273 に答える
1
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

cipher.init(Cipher.DECRYPT_MODE, key);
cipher.update(cipherBytes);

// byte[] plaintext = cipher.doFinal(cipherBytes);
//                                   ^-- You shouldn't pass cipherBytes twice.
//                                   v-- instead use the parameter-less method:
byte[] plaintext    = cipher.doFinal();
于 2012-08-24T16:05:48.190 に答える