How to generate Content Encryption Key for JWE implementation

3.6k Views Asked by At

I am trying to learn and implement JWE in java for a problem statement. I am trying to understand how does the Content Encryption Key is generated using a certain algorithm(let's say RSA-PKCS1_1.5).

I have knowledge on how to generate a pair of the key using the key generator, then using the public key for encryption and private key for decryption. Also, I am aware of how to create a simple JWT token by giving claims and also how to sign them. I am trying to follow the steps:

The message encryption process is as follows:

Generate a random Content Encryption Key (CEK). The CEK MUST have a length at least equal to that of the required encryption keys and MUST be generated randomly.

Encrypt the CEK for the recipient

Generate a random IV (if required for the algorithm).

Compress the Plaintext if a zip parameter was included.

Serialize the (compressed) Plaintext into a bitstring M.

Encrypt M using the CEK and IV to form the bitstring C.

Set the Encoded JWE Ciphertext equal to the base64url encoded representation of C.

Create a JWE Header containing the encryption parameters used.

Base64url encode the bytes of the UTF-8 representation of the JWE Header to create the Encoded JWE Header.

The three encoded parts, taken together, are the result of the encryption.

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

There are 1 best solutions below

0
Spomky-Labs On

Key Management Mode

The key management mode is used to determine the CEK. Each algorithm uses one of these modes. Hereafter the list of available modes and algorithm associations:

  • Key Encryption: RSA1_5, RSA-OAEP, RSA-OAEP-256, RSA-OAEP-384, RSA-OAEP-512
  • Key Wrapping: A128KW, A192KW, A256KW, PBES2-HS256+A128KW, PBES2-HS384+A192KW, PBES2-HS512+A256KW, A128GCMKW, A192GCMKW, A256GCMKW
  • Direct Key Agreement: ECDH-ES
  • Key Agreement with Key Wrapping: ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW
  • Direct Encryption: dir

How to determine the CEK?

  • With Key Encryption, Key Wrapping and Key Agreement with Key Wrapping, the CEK is a random byte string. Its size depends on the Content Encryption Algorithm.
  • With Direct Key Agreement, the CEK is the agreed upon key computed using the sender and receiver keys.
  • With Direct Encryption, the CEK is the shared symmetric key.