Class PqcClientCryptoUtil

java.lang.Object
co.ankatech.ankasecure.sdk.util.PqcClientCryptoUtil

public final class PqcClientCryptoUtil extends Object
PqcClientCryptoUtil

Provides client-side cryptographic utilities for hybrid or post-quantum schemes. It includes:

  • Generating key pairs for the PQC transport KEMs (ML-KEM, HQC, FrodoKEM; see AsymmetricAlgorithmRegistry).
  • AES-GCM encryption/decryption with ephemeral IV usage, ensuring no IV reuse.
  • KEM decapsulation to recover a symmetric key from the server's KEM ciphertext.

This class emphasizes strong security practices, using the JDK's NIST SP 800-90A DRBG mechanism via CryptoRandomProvider and never reusing ephemeral data. All methods log important steps and errors using devLogger for development-level detail and userLogger for user-facing issues. Additionally, messages are internationalized via a ResourceBundle.

Example usage:

Designed to integrate with standard Java 17+ runtimes.

  • Field Details

    • CIPHER_INPUT_STREAM_BUFFER_SIZE

      public static final int CIPHER_INPUT_STREAM_BUFFER_SIZE
      See Also:
  • Method Details

    • generateKeyPair

      public static PqcClientCryptoUtil.GeneratedKeyPair generateKeyPair(String algorithm) throws CryptoOperationException
      Generates a key pair for one of the PQC transport KEMs (AsymmetricAlgorithmRegistry.supportedKems()). The Bouncy Castle name, provider and parameter set come from the registry; randomness comes from CryptoRandomProvider.
      Parameters:
      algorithm - the catalogue name of the KEM (e.g. "ML-KEM-768", "HQC-128", "FRODO-976")
      Returns:
      a PqcClientCryptoUtil.GeneratedKeyPair with both raw objects and Base64-encoded strings
      Throws:
      InvalidInputException - if algorithm is not a transport KEM
      CryptoOperationException - if any unexpected error occurs
    • encryptDataRaw

      public static byte[] encryptDataRaw(SecretBuffer aesKeyBuf, byte[] plaintext) throws CryptoOperationException
      SecretBuffer overload of encryptDataRaw(byte[], byte[]).

      The caller passes a SecretBuffer wrapping the AES key bytes; this method forwards to the byte[]-key implementation. The SecretBuffer's lifecycle is owned by the caller (typically via try-with-resources at the call site, e.g., PqcTransportInterceptor). The byte[]-key overload is preserved for callers who own their own key bytes (caller-owned semantics).

      Parameters:
      aesKeyBuf - SecretBuffer wrapping the AES key bytes
      plaintext - data to be encrypted (can be null or empty)
      Returns:
      the ciphertext including IV metadata
      Throws:
      CryptoOperationException - if encryption fails
    • encryptDataRaw

      public static byte[] encryptDataRaw(byte[] aesKeyBytes, byte[] plaintext) throws CryptoOperationException
      Throws:
      CryptoOperationException
    • decryptDataRaw

      public static byte[] decryptDataRaw(SecretBuffer aesKeyBuf, byte[] ciphertext) throws CryptoOperationException
      SecretBuffer overload of decryptDataRaw(byte[], byte[]).

      Mirrors the encryptDataRaw SecretBuffer overload; caller owns the SecretBuffer lifecycle.

      Parameters:
      aesKeyBuf - SecretBuffer wrapping the AES key bytes
      ciphertext - the ciphertext blob including IV and tag
      Returns:
      decrypted plaintext
      Throws:
      CryptoOperationException - if decryption fails
    • decryptDataRaw

      public static byte[] decryptDataRaw(byte[] aesKeyBytes, byte[] ciphertext) throws CryptoOperationException
      Throws:
      CryptoOperationException
    • decapsulateKem

      public static byte[] decapsulateKem(PrivateKey privateKey, String kemAlgorithm, byte[] ciphertext) throws CryptoOperationException

      Decapsulates and decrypts a ciphertext using the provided PrivateKey. Instead of merely extracting the AES key, this method:

      • Reads wrappedKey + IV from the ciphertext.
      • Unwraps the AES key with the private key.
      • Performs AES-GCM decryption on the remaining data.
      • Returns the fully decrypted plaintext bytes.

      Parameters:
      privateKey - the private key used to unwrap the AES key
      kemAlgorithm - the catalogue name of the KEM the private key was generated with (e.g. "ML-KEM-768", "HQC-128")
      ciphertext - the full ciphertext (containing [wrappedKey, IV, and encrypted data]) as a single byte array
      Returns:
      the decrypted plaintext bytes
      Throws:
      CryptoOperationException - if any cryptographic or I/O error occurs