Ja sám implementujem režim CBC. A A používam ako funkciu E pre každý blok CBC.
Tu je môj kódovací kód:
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));
}
používam update
pretože nechcem pridať AES podložku, robím to sám pre posledný blok na začiatku CBC algorytmu.
Keď chcem dešifrovať cyphertext blok, používam rovnakú funkciu s 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));
}
Problémom je to Cipher.update
v dešifrovacom režime vráti prázdne bajtové pole pre vstup, ktorý bol zašifrovaný pomocou encrypt
metóda.
Čo je zlé?
odpovede:
2 pre odpoveď č. 1Chýba vám hovor doFinal
, Kvôli čalúneniu pre šifrovanie v režime ECB a CBC, Cipher
inštancie sú potrebné na vyrovnávaciu pamäť až do veľkosti bloku - 1 bajtov, ktoré budú len polstrované a zašifrované (alebo dešifrované a nekódované) v doFinal()
volanie, ktoré uvoľní poslednú časť ciphertext (alebo plaintext pre dešifrovanie).
Čo by ste mali urobiť, je použiť "AES/ECB/NoPadding"
a len doFinal
namiesto update
na implementovať CBC pre každý blok (hoci len update
môže fungovať, ale nie je to 100% špecifikovanéMalo by). Toto je identické s blokovaním šifrovania základnej šifry AES. Môžete tiež použiť nižšiu úroveň, ľahký (tzn .: priamy, non-JCE) API Bouncy Castle, ktorý poskytuje AES motory ktoré implementujú samotnú blokovú šifru.