Разрушение RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING

Итак, у Java есть режим с именем RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING. Что это значит?

RFC3447, Стандарты криптографии с открытым ключом (PKCS) # 1: Спецификации шифрования RSA Версия 2.1, раздел 7.1.2 Операция дешифрования говорит Hash и MGF - оба варианта для RSAES-OAEP-DECRYPT. MGF - это собственная функция, определенная в разделе B.2.1 MGF1, и которая также имеет собственную опцию Hash.

Возможно, опция "Хэш" в RSAES-OAEP-DECRYPT и MGF1 должна быть одинаковой или, может быть, нет, для меня это непонятно. Если они тогда, я думаю, когда у вас есть RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING, значит, sha256 должен использоваться для обоих. Но если они не должны быть одинаковыми, вы можете использовать sha256 для RSAES-OAEP-DECRYPT и, например, sha1, используемый для MGF1. И если это случай, то какая функция sha256 должна использоваться? И какой хэш-алгоритм предполагается использовать для другой функции?

И что означает ECB в этом контексте? ECB является симметричным блочным шифровым режимом. Электронная кодовая книга. Может быть, это должно означать, что Java работает с открытым текстом, который больше, чем по модулю? Как, возможно, разделяет открытый текст на куски, которые являются такими же большими, как и по модулю, а затем шифрует каждый из них с помощью RSA и объединяет их вместе? Я просто догадываюсь.

Ответ 1

По умолчанию для OAEP используется SHA-1 для MGF1. Обратите внимание, что выбранный хеш не оказывает большого влияния на безопасность OAEP, поэтому в большинстве случаев он будет оставлен по умолчанию.

Мы можем легко проверить это, протестировав его с "OAEPPadding" и OAEPParameterSpec:

// --- we need a key pair to test encryption/decryption
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024); // speedy generation, but not secure anymore
KeyPair kp = kpg.generateKeyPair();
RSAPublicKey pubkey = (RSAPublicKey) kp.getPublic();
RSAPrivateKey privkey = (RSAPrivateKey) kp.getPrivate();

// --- encrypt given algorithm string
Cipher oaepFromAlgo = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
oaepFromAlgo.init(Cipher.ENCRYPT_MODE, pubkey);
byte[] ct = oaepFromAlgo.doFinal("owlstead".getBytes(StandardCharsets.UTF_8));

// --- decrypt given OAEPParameterSpec
Cipher oaepFromInit = Cipher.getInstance("RSA/ECB/OAEPPadding");
OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-1"), PSpecified.DEFAULT);
oaepFromInit.init(Cipher.DECRYPT_MODE, privkey, oaepParams);
byte[] pt = oaepFromInit.doFinal(ct);
System.out.println(new String(pt, StandardCharsets.UTF_8));

Код не будет выполнен с исключением, связанным с заполнением, если вы замените MGF1 в качестве параметра "SHA-256".

Причина, по которой расширенный алгоритм нужен вообще, заключается в совместимости с другими алгоритмами Cipher. Код, написанный, например, для "RSA/ECB/PKCS1Padding", не использует никаких параметров, не говоря уже о параметрах OAEP. Таким образом, без более длинной строки OAEP не может функционировать как замена.


Режим работы "ECB" ничего не значит в этом контексте, он должен был быть "None" или он должен был быть полностью исключен. Вы можете зашифровать только один блок, используя реализацию RSA поставщика SunRSA.

Если вы хотите зашифровать больше данных, создайте случайный (AES) симметричный ключ и зашифруйте его, используя OAEP. Затем используйте ключ AES для шифрования ваших конкретных данных. Это называется гибридной криптосистемой, поскольку для шифрования данных используются как асимметричные, так и симметричные примитивы.


Обратите внимание, что OAEP не поддерживается в JDK 7 (1.7) или более ранних версиях. OAEP включен в требования к реализации для сред выполнения Java начиная с Java 8:

  • RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
  • RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)