/ / AES javax.crypto.Cipherは復号化モードで空の配列を返します - java、暗号化、暗号化、aes、cbc-mode

AES。 javax.crypto.Cipherは、復号化モードで空の配列を返します - java、暗号化、暗号化、aes、cbc-mode

私は自分でCBCモードを実装しています。そして各CBCブロックのE関数としてAESを使います。

これが私の暗号化コードです。

public static List<Byte> encrypt(List<Byte> bytes, byte[] key) throws Exception {
byte[] bytesArray = BytesConverter.toByteArray(bytes);

SecretKey secretKey = new SecretKeySpec(key, AES);

Cipher cipher = Cipher.getInstance(AES);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);

return BytesConverter.toByteList(cipher.update(bytesArray));
}

私が使う update 私はAESパッドを追加したくないので、CBCアルゴリズムの開始時に最後のブロックのために自分でそれを行います。

暗号文ブロックを復号化するときは、Cipher.DECRYPTION_MODEと同じ関数を使用します。

public static List<Byte> decrypt(List<Byte> bytes, byte[] key) throws Exception {
byte[] bytesArray = BytesConverter.toByteArray(bytes);

SecretKey secretKey = new SecretKeySpec(key, AES);

Cipher cipher = Cipher.getInstance(AES);
cipher.init(Cipher.DECRYPT_MODE, secretKey);

return BytesConverter.toByteList(cipher.update(bytesArray));
}

問題は、 Cipher.update 復号化モードでは、暗号化された入力に対して空のバイト配列を返します。 encrypt 方法。

混乱しています。どうしたのですか。

回答:

回答№1は2

への通話がありません doFinal。 ECBおよびCBCモードの暗号化のためのパディングのため、 Cipher インスタンスは、最大1ブロックのブロックサイズまでバッファリングする必要があります。このサイズは、パディングと暗号化(または復号化と非パディング)のみが行われます。 doFinal() 暗号文の最後の部分(または復号化のための平文)を解放するcall。

あなたがすべきことは、使用することです "AES/ECB/NoPadding" 唯一の doFinal の代わりに updateCBCを実装する 各ブロックごとに update うまくいくかもしれませんが、それが100%指定されているわけではありません。そうすべき)。これは、基礎となるAES暗号のブロック暗号化と同じです。 AESを提供するBouncy Castleの低レベル、軽量(すなわち、直接、非JCE)APIも使用できます。 エンジン これはブロック暗号自体を実装するだけです。