При дешифровании с использованием Java Cipher с «AES / CBC / PKCS5Padding» необходимо указать IV? и только SecretKeyFactory можно использовать? - PullRequest
2 голосов
/ 15 апреля 2020

Я прочитал несколько примеров использования Java Cipher для шифрования и дешифрования данных. Например:

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = new SecureRandom();
keyGenerator.init(256, secureRandom);
SecretKey secretKey = keyGenerator.generateKey();
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, secretKey);

У меня есть 2 вопроса о процессе расшифровки.

  1. Несмотря на то, что требуется IV, мы можем оставить его неявным, используя Cipher.init(Cipher.ENCRYPT_MODE, Key). Случайный IV будет автоматически применен к нему. Однако в режиме дешифрования должен использоваться тот же IV. Означает ли это, что следует использовать только Cipher.init(int opmode, Key key, AlgorithmParameters params), и IV следует получить из шифрования, сохранить и передать здесь?

Кроме '' KeyGenerator '', я также видел пример чтобы сгенерировать ключ с помощью '' 'SecretKeyFactory' '':

String key = ...
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKeySpec keySpec = factory.generateSecret(new DESKeySpec(key));

Полагаю, я могу использовать его для AES, если я изменю последнюю строку на

SecretKeySpec keySpec = factory.generateSecret(new SecretKeySpec(key,"AES"));
Я не понимаю, когда использовать SecretKeyFactory для генерации ключа и когда использовать KeyGenerator. Кажется, что последний генерирует случайный ключ, первый генерируется из данного материала ключа. Значит ли это, что в режиме расшифровки можно использовать только SecretKeyFactory?

1 Ответ

0 голосов
/ 15 апреля 2020

Означает ли это, что следует использовать только Cipher.init(int opmode, Key key, AlgorithmParameters params), а IV следует получить из шифрования, сохранить и передать здесь?

Да, именно так, если только вы не можете сообщать об этом другими способами. Как правило, хотя IV рандомизируется во время шифрования, затем префикс перед зашифрованным текстом. Для AES-CB C это всегда тот же размер, что и размер блока: 16 байтов.

Так значит ли это, что в режиме дешифрования можно использовать только SecretKeyFactory?

Да, хотя для AES есть небольшой аккуратный ярлык; Вы можете просто сделать:

SecretKey aesKey = new SecretKeySpec(keyBytes, "AES");

и покончить с этим. Это потому, что SecretKeySpec реализует SecretKey. Для ключей 3DES это не очень хорошая идея, потому что это будет означать, что биты четности DES установлены неправильно. Однако современные ключи, такие как ключи AES и ключи HMA C, состоят исключительно из случайных данных, поэтому для них это хорошо. Есть одно предостережение: это будет проблемой, если вы попытаетесь сгенерировать ключ на аппаратном устройстве таким образом: он должен храниться в программном обеспечении.

Обратите внимание, что я не буду слишком углубляться в управление ключами и как ключи должны быть созданы. Я ответил на этот вопрос здесь , хотя этот ответ, безусловно, далеко не полный. Черт возьми, вы можете использовать кости и обмениваться номерами по телефону для меня все равно :)

...