Cipher で作業したとき、次のことがわかりました。
暗号化コード:
Cipher aes = Cipher.getInstance("AES");
aes.init(Cipher.ENCRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());
復号化コード:
Cipher aes = Cipher.getInstance("AES");
aes.init(Cipher.DECRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());
復号化コードを実行すると、IllegalBlockSizeException(入力長は16の倍数である必要があります...)が発生します。
しかし、復号化コードをに変更すると
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding"); //I am passing the padding too
aes.init(Cipher.DECRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());
それはうまくいきます。 algorithm/mode/padding
のパターンであると理解しています。だから、パディングについては触れなかったからだと思いました。だから私は暗号化中にモードとパディングを与えてみました、
暗号化コード:
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");//Gave padding during encryption too
aes.init(Cipher.ENCRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());
復号化コード:
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
aes.init(Cipher.DECRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());
ただし、IllegalBlockSizeExceptionで失敗します。
理由、例外の理由、およびその下で正確に何が起こっているのか。誰かが助けることができれば?前もって感謝します
[〜#〜]更新[〜#〜]
問題は、暗号化および復号化する文字列にあるようです。なぜなら、私が言ったコードでさえ、常に機能するとは限らないからです。私は基本的にUUIDを暗号化しています(例:8e7307a2-ef01-4d7d-b854-e81ce152bbf6)。特定の文字列で機能し、特定の他の文字列では機能しません。
暗号化された文字列の長さは64で、16で割り切れます。はい、同じマシンで実行しています。
秘密鍵の生成方法:
private Key generateKey() throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA");
String passphrase = "blahbl blahbla blah";
digest.update(passphrase.getBytes());
return new SecretKeySpec(digest.digest(), 0, 16, "AES");
}
復号化中に、入力データがブロックサイズの倍数(AESの場合は16バイト)でない場合、のみIllegalBlockSizeException
を取得できます。
キーまたはデータが無効である(ただし長さが正しい)場合、平文ではPKCS#5のパディングが間違っているため、BadPaddingException
が返されます。非常にまれに、パディングが偶然に正しく表示され、例外はまったくありません。
N.B.常にパディングとモードを指定することをお勧めします。そうしないと、プロバイダーがデフォルトを変更した場合に驚かされる可能性があります。 AFAIK、Sunプロバイダーは"AES"
を"AES/ECB/PKCS5Padding"
に変換します。