0

に問題があります

javax.crypto.Cipher

このコード行を書くとき

    Cipher cipher;
    byte[] bytes = null;

    try
    {
        cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, generateAESKey128b(key));
        bytes = cipher.doFinal(input.getBytes("UTF-8"));
    }
    catch (NoSuchAlgorithmException e)
    {
        e.printStackTrace();
    }
    catch (NoSuchPaddingException e)
    {
        e.printStackTrace();
    }
    catch (InvalidKeyException e)
    {
        e.printStackTrace();
    }
    catch (UnsupportedEncodingException e)
    {
        e.printStackTrace();
    }
    catch (IllegalBlockSizeException e)
    {
        e.printStackTrace();
    }
    catch (BadPaddingException e)
    {
        e.printStackTrace();
    }

コンソールからこのエラーが発生します

javax.crypto.IllegalBlockSizeException 
Input length must be multiple of 16 when    
decrypting with padded cipher
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at it.unitn.se.gym.backend.utils.Security.AES128Decode(Security.java:109)
at it.unitn.se.gym.backend.utils.Security.decode_AES128_Base64(Security.java:96)
at it.unitn.se.gym.backend.WebService.main(WebService.java:42)
Exception in thread "main" java.lang.NullPointerException
at it.unitn.se.gym.backend.utils.Security.decode_AES128_Base64(Security.java:97)
at it.unitn.se.gym.backend.WebService.main(WebService.java:42)

コードの最初の2行は正しいですが、byte[]型の属性"text"をdoFinal関数に渡すと、エラーが発生します。

誰かが理由を教えてもらえますか?

解決済み:

さて、問題は解決しました

byte[] encrypted = UniversalBase64Encoder.decode(input);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, generateAESKey128b(key));
byte[] originalBytes = cipher.doFinal(encrypted);

これは私が書いた正しいコードです

4

1 に答える 1

1

問題は、暗号化されていない文字列を復号化しようとしており、復号化アルゴリズムの前提 (入力サイズは常に 16 の倍数である) に違反していることです。

文字列を暗号化してから復号化するコード ブロックを次に示します。暗号化された文字列が出力されると、入力文字列はそうではありませんが、長さが 16 バイトになることに注意してください。暗号化アルゴリズムは、入力文字列を暗号化する前に 16 バイトの倍数になるようにパディングします。この 16 バイト長の暗号化された文字列は、復号化の有効な入力になります。

この仮定 (暗号化の結果は均等なサイズになる) は、非常に標準的なものです。これにより、復号化/暗号化アルゴリズムの記述が容易になるだけでなく、暗号化されたものの長さを攻撃者が知ることもできなくなります。

byte[] keyBytes = new byte[16];
keyBytes[0] = 1;
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
String input = "hello";
Cipher cipher;
byte[] bytes = null;
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
bytes = cipher.doFinal(input.getBytes("UTF-8"));

System.out.println("Encoded: "+Arrays.toString(bytes));

cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decoded = cipher.doFinal(bytes);

System.out.println("Decoded: "+new String(decoded, "UTF-8"));
于 2013-03-19T13:19:52.643 に答える