Skip to main content

Overview

The javax.crypto package provides the Java Cryptographic Extension (JCE) framework for:
  • Symmetric Encryption: AES, ChaCha20, DES algorithms
  • Key Generation: Secret key generation for symmetric algorithms
  • Key Agreement: Diffie-Hellman and ECDH key agreement
  • Message Authentication: MAC (Message Authentication Code) generation
  • Key Derivation: Password-based key derivation (PBKDF2)
  • Key Wrapping: Secure key transport

Core Classes

Cipher

Provides the functionality of a cryptographic cipher for encryption and decryption.
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.security.SecureRandom;

public class CipherExample {
    public static byte[] encryptAES(byte[] plaintext, SecretKey key) 
            throws Exception {
        // Create cipher instance with AES/GCM/NoPadding
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        
        // Generate random IV
        byte[] iv = new byte[12]; // 96 bits for GCM
        SecureRandom random = new SecureRandom();
        random.nextBytes(iv);
        
        // Initialize for encryption
        GCMParameterSpec spec = new GCMParameterSpec(128, iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, spec);
        
        // Encrypt
        byte[] ciphertext = cipher.doFinal(plaintext);
        
        // In practice, prepend IV to ciphertext for transmission
        return ciphertext;
    }
}
getInstance(String transformation)
static Cipher
Returns a Cipher object that implements the specified transformation.Transformation Format: algorithm/mode/padding or just algorithmRequired transformations (all Java platforms):
  • AES/CBC/NoPadding (128)
  • AES/CBC/PKCS5Padding (128)
  • AES/ECB/NoPadding (128)
  • AES/ECB/PKCS5Padding (128)
  • AES/GCM/NoPadding (128, 256)
  • ChaCha20-Poly1305
  • RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
  • RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
Throws:
  • NoSuchAlgorithmException - if transformation is null, empty, or invalid
  • NoSuchPaddingException - if padding scheme is not available
init(int opmode, Key key)
void
Initializes this cipher with a key.Operation modes:
  • Cipher.ENCRYPT_MODE - Encrypt mode
  • Cipher.DECRYPT_MODE - Decrypt mode
  • Cipher.WRAP_MODE - Key wrapping mode
  • Cipher.UNWRAP_MODE - Key unwrapping mode
Throws:
  • InvalidKeyException - if the key is inappropriate for initializing this cipher
update(byte[] input)
byte[]
Continues a multiple-part encryption or decryption operation. Returns the next chunk of processed data, or null if no output is produced.
doFinal()
byte[]
Finishes a multiple-part encryption or decryption operation. Returns the last chunk of processed data.Throws:
  • IllegalBlockSizeException - if total input length is not multiple of block size (for encryption)
  • BadPaddingException - if decryption detects incorrect padding
doFinal(byte[] input)
byte[]
Encrypts or decrypts data in a single-part operation. Equivalent to calling update(input) followed by doFinal().
getIV()
byte[]
Returns the initialization vector (IV) in a new buffer. Useful when a random IV was created.
getBlockSize()
int
Returns the block size (in bytes). Returns 0 if this cipher is not a block cipher.
For AEAD modes like GCM, call doFinal() to verify the authentication tag. An AEADBadTagException will be thrown if verification fails.
Important Security Notes:
  • Always use authenticated encryption modes (GCM, ChaCha20-Poly1305) when possible
  • Never reuse an IV with the same key for GCM mode
  • Use a random IV for CBC mode
  • For GCM: IV should be 12 bytes (96 bits) for optimal performance

KeyGenerator

Provides the functionality of a secret (symmetric) key generator.
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class KeyGenExample {
    public static SecretKey generateAESKey(int keySize) throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(keySize); // 128, 192, or 256 bits
        return keyGen.generateKey();
    }
}
getInstance(String algorithm)
static KeyGenerator
Returns a KeyGenerator object that generates secret keys for the specified algorithm.Required algorithms (all Java platforms):
  • AES (128, 256)
  • ChaCha20
  • HmacSHA1
  • HmacSHA256
Throws:
  • NoSuchAlgorithmException - if no provider supports the algorithm
init(int keysize)
void
Initializes this key generator for a certain keysize (in bits).Throws:
  • InvalidParameterException - if keysize is wrong or not supported
init(int keysize, SecureRandom random)
void
Initializes this key generator for a certain keysize, using a user-provided source of randomness.
generateKey()
SecretKey
Generates a secret key.

SecretKey

Interface for secret (symmetric) keys. This interface contains no methods; it serves to group and provide type safety for secret keys.
SecretKey Usage
SecretKey key = keyGen.generateKey();

// Get algorithm
String algorithm = key.getAlgorithm(); // e.g., "AES"

// Get encoded form
byte[] encoded = key.getEncoded();

// Get format
String format = key.getFormat(); // typically "RAW"

Mac

Provides the functionality of a Message Authentication Code (MAC) algorithm.
import javax.crypto.Mac;
import javax.crypto.SecretKey;

public class MacExample {
    public static byte[] generateHMAC(byte[] data, SecretKey key) 
            throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(key);
        return mac.doFinal(data);
    }
}
getInstance(String algorithm)
static Mac
Returns a Mac object that implements the specified MAC algorithm.Common algorithms:
  • HmacSHA1
  • HmacSHA256
  • HmacSHA384
  • HmacSHA512
init(Key key)
void
Initializes this Mac object with the given key.Throws:
  • InvalidKeyException - if the given key is inappropriate
update(byte[] input)
void
Processes the given array of bytes.
doFinal()
byte[]
Finishes the MAC operation and returns the MAC result. Resets the Mac object.

Advanced Features

Password-Based Encryption

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.spec.KeySpec;

public class PBEExample {
    public static SecretKey deriveKey(char[] password, byte[] salt) 
            throws Exception {
        SecretKeyFactory factory = SecretKeyFactory.getInstance(
            "PBKDF2WithHmacSHA256");
        
        KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
        SecretKey tmp = factory.generateSecret(spec);
        
        return new SecretKeySpec(tmp.getEncoded(), "AES");
    }
}

Key Agreement

Diffie-Hellman
import javax.crypto.KeyAgreement;
import java.security.*;

public class KeyAgreementExample {
    public static SecretKey performDH(PrivateKey privateKey, 
                                     PublicKey publicKey) throws Exception {
        KeyAgreement keyAgree = KeyAgreement.getInstance("DH");
        keyAgree.init(privateKey);
        keyAgree.doPhase(publicKey, true);
        
        // Generate shared secret
        byte[] sharedSecret = keyAgree.generateSecret();
        
        // Derive AES key from shared secret
        MessageDigest hash = MessageDigest.getInstance("SHA-256");
        byte[] derivedKey = hash.digest(sharedSecret);
        
        return new SecretKeySpec(derivedKey, 0, 16, "AES");
    }
}

Sealed Objects

SealedObject
import javax.crypto.SealedObject;

public class SealedObjectExample {
    public static SealedObject sealObject(Serializable object, Cipher cipher) 
            throws Exception {
        return new SealedObject(object, cipher);
    }
    
    public static Object unsealObject(SealedObject sealed, Cipher cipher) 
            throws Exception {
        return sealed.getObject(cipher);
    }
}

Exception Handling

Thrown when decryption detects incorrect padding. Usually indicates:
  • Wrong key used for decryption
  • Corrupted ciphertext
  • Tampering detected
try {
    byte[] plaintext = cipher.doFinal(ciphertext);
} catch (BadPaddingException e) {
    // Handle decryption failure
    System.err.println("Decryption failed - wrong key or corrupted data");
}

Best Practices

Security Recommendations:
  1. Use Authenticated Encryption: Prefer AES/GCM/NoPadding or ChaCha20-Poly1305
  2. Key Sizes: Use 256-bit keys for AES when possible
  3. IV Management:
    • Generate random IVs for each encryption
    • Never reuse IV with same key (especially for GCM)
  4. Password-Based Encryption: Use high iteration counts (65536+)
  5. Key Storage: Store keys securely using KeyStore

Thread Safety

Most classes in javax.crypto are NOT thread-safe:
  • Cipher - Not thread-safe
  • KeyGenerator - Not thread-safe after initialization
  • Mac - Not thread-safe

See Also

Build docs developers (and LLMs) love