BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Modern Cryptography in OpenJDK: Introduction of Key Encapsulation Mechanisms API

Modern Cryptography in OpenJDK: Introduction of Key Encapsulation Mechanisms API

JEP 452, Key Encapsulation Mechanism API, has been promoted from Targeted to Completed for JDK 21. This JEP introduces an API for Key Encapsulation Mechanisms (KEMs), a modern encryption technique for securing symmetric keys using public key cryptography. The new API aims to enable applications to use KEM algorithms such as RSA Key Encapsulation Mechanism (RSA-KEM), Elliptic Curve Integrated Encryption Scheme (ECIES), and candidate KEM algorithms for the National Institute of Standards and Technology (NIST) Post-Quantum Cryptography standardization process.

KEMs are a crucial tool for defending against quantum attacks. The traditional technique of securing symmetric keys involves encrypting a randomly generated symmetric key with a public key. However, this requires padding and can be challenging to prove secure. KEMs, on the other hand, use properties of the public key to derive a related symmetric key, eliminating the need for padding.

The new API will also enable the use of KEMs in higher-level protocols such as Transport Level Security (TLS) and in cryptographic schemes such as Hybrid Public Key Encryption (HPKE, RFC 9180). It will allow security providers to implement KEM algorithms in either Java code or native code. However, it is not a goal to include key pair generation in the KEM API, as the existing KeyPairGenerator API is sufficient.

The KEM API consists of three functions: a key pair generation function, a key encapsulation function, and a key decapsulation function. The key pair generation function is covered by the existing KeyPairGenerator API, while the encapsulation and decapsulation functions are defined in a new class, KEM. Consider the following code snippets:

package javax.crypto;

public class DecapsulateException extends GeneralSecurityException;

public final class KEM {

    public static KEM getInstance(String alg)
        throws NoSuchAlgorithmException;
    public static KEM getInstance(String alg, Provider p)
        throws NoSuchAlgorithmException;
    public static KEM getInstance(String alg, String p)
        throws NoSuchAlgorithmException, NoSuchProviderException;

    public static final class Encapsulated {
        public Encapsulated(SecretKey key, byte[] encapsulation, byte[] params);
        public SecretKey key();
        public byte[] encapsulation();
        public byte[] params();
    }

    public static final class Encapsulator {
        String providerName();
        int secretSize();           // Size of the shared secret
        int encapsulationSize();    // Size of the key encapsulation message
        Encapsulated encapsulate();
        Encapsulated encapsulate(int from, int to, String algorithm);
    }

    public Encapsulator newEncapsulator(PublicKey pk)
            throws InvalidKeyException;
    public Encapsulator newEncapsulator(PublicKey pk, SecureRandom sr)
            throws InvalidKeyException;
    public Encapsulator newEncapsulator(PublicKey pk, AlgorithmParameterSpec spec,
                                        SecureRandom sr)
            throws InvalidAlgorithmParameterException, InvalidKeyException;

    public static final class Decapsulator {
        String providerName();
        int secretSize();           // Size of the shared secret
        int encapsulationSize();    // Size of the key encapsulation message
        SecretKey decapsulate(byte[] encapsulation) throws DecapsulateException;
        SecretKey decapsulate(byte[] encapsulation, int from, int to,
                              String algorithm)
                throws DecapsulateException;
    }

    public Decapsulator newDecapsulator(PrivateKey sk)
            throws InvalidKeyException;
    public Decapsulator newDecapsulator(PrivateKey sk, AlgorithmParameterSpec spec)
            throws InvalidAlgorithmParameterException, InvalidKeyException;

}

The getInstance methods create a new KEM object that implements the specified algorithm. The sender calls one of the newEncapsulator methods, which takes the receiver's public key and returns an Encapsulator object. The sender can then call one of that object's encapsulate methods to get an Encapsulated object, which contains a SecretKey and a key encapsulation message.

The receiver calls one of the newDecapsulator methods, which takes the receiver's private key and returns a Decapsulator object. The receiver can then call one of that object's decapsulate methods, which takes the received key encapsulation message and returns the shared secret.


The introduction of the KEM API in OpenJDK is a significant step forward in modern cryptography, providing a more secure and efficient way to secure symmetric keys using public key cryptography. It is expected to play a crucial role in defending against quantum attacks and enhancing the security of higher-level protocols and cryptographic schemes.

 

About the Author

Rate this Article

Adoption
Style

BT