Как сгенерировать ключ шифрования содержимого для реализации JWE

#encryption #jwe #jceks

#шифрование #jwe #jceks

Вопрос:

Я пытаюсь изучить и реализовать JWE на Java для постановки задачи. Я пытаюсь понять, как ключ шифрования содержимого генерируется с использованием определенного алгоритма (скажем, RSA-PKCS1_1.5).

У меня есть знания о том, как сгенерировать пару ключей с помощью генератора ключей, затем используя открытый ключ для шифрования и закрытый ключ для дешифрования. Кроме того, я знаю, как создать простой токен JWT, предоставив утверждения, а также как их подписать. Я пытаюсь следовать инструкциям:

Процесс шифрования сообщения заключается в следующем:

Сгенерируйте случайный ключ шифрования содержимого (CEK). CEK ДОЛЖЕН иметь длину, по крайней мере, равную длине требуемых ключей шифрования, и должен генерироваться случайным образом.

Зашифруйте CEK для получателя

Сгенерируйте случайный IV (если требуется для алгоритма).

Сжать открытый текст, если был включен параметр zip.

Сериализовать (сжатый) Открытый текст в битовую строку M.

Зашифруйте M, используя CEK и IV для формирования битовой строки C.

Установите кодированный зашифрованный текст JWE равным представлению C. в кодировке base64url.

Создайте заголовок JWE, содержащий используемые параметры шифрования.

Base64url кодирует байты представления заголовка JWE в формате UTF-8 для создания закодированного заголовка JWE.

Три закодированные части, взятые вместе, являются результатом шифрования.

 public static void main(String[] args)
            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        //ASYMMETRIC ENCRYPTION
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        KeyPair keys = keyPairGenerator.generateKeyPair();
        byte[] publicKey = keys.getPublic().getEncoded();
        byte[] privateKey = keys.getPrivate().getEncoded();

        System.out.println("PUBLIC KEY  ::: "   Base64.encodeBase64String(publicKey));
        System.out.println("PRIVATE KEY ::: "   Base64.encodeBase64String(privateKey));

        Cipher cipher = Cipher.getInstance("RSA");
        //PUBLIC KEY IS GETTING USED IN ENCRYPTING PLAIN TEXT
        cipher.init(Cipher.ENCRYPT_MODE, keys.getPublic());
        byte[] encryptedBytes = cipher.doFinal("Test String".getBytes());
        //PRIVATE KEY IS GETTING USED IN DECRYPTING CIPHER TEXT
        cipher.init(Cipher.DECRYPT_MODE, keys.getPrivate());
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

        System.out.println("encrypted data  ::: "   BaseEncoding.base64().encode(encryptedBytes));
        System.out.println("decrypted text ::: "   new String(decryptedBytes));
}
  

Ответ №1:

Режим управления ключами

Режим управления ключами используется для определения CEK. Каждый алгоритм использует один из этих режимов. Далее приведен список доступных режимов и ассоциаций алгоритмов:

  • Шифрование ключа: RSA1_5 , RSA-OAEP RSA-OAEP-256 , RSA-OAEP-384 ,,,, RSA-OAEP-512
  • Ключ Упаковка: A128KW , A192KW , A256KW , PBES2-HS256 A128KW , PBES2-HS384 A192KW , PBES2-HS512 A256KW , A128GCMKW , A192GCMKW , A256GCMKW
  • Прямое соглашение о ключе: ECDH-ES
  • Соглашение о ключе с переносом ключей: ECDH-ES A128KW , ECDH-ES A192KW , ECDH-ES A256KW
  • Прямое шифрование: dir

Как определить CEK?

  • При шифровании ключа, переносе ключа и согласовании ключа с переносом ключа CEK представляет собой строку случайных байтов. Его размер зависит от алгоритма шифрования содержимого.
  • При прямом соглашении о ключе CEK является согласованным ключом, вычисляемым с использованием ключей отправителя и получателя.
  • При прямом шифровании CEK является общим симметричным ключом.