skip to content

KeyGenerator, KeyPairGenerator & KeyStore

Generating symmetric keys with KeyGenerator and key pairs with KeyPairGenerator, seeding them from SecureRandom, and persisting them in a PKCS12 or JKS KeyStore under aliases. Interviewers move quickly from generating keys to where you actually store them.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

How do you generate a symmetric secret key in Java using KeyGenerator, and what does init() control?

level: juniorimportance: must knowfreq 60%

answer

  1. getInstance -> init(size) -> generateKey
  2. KeyGenerator = symmetric (AES, HMAC)
  3. init sets bit-length + SecureRandom
  4. skip init = provider default (can be weak)
  5. returns SecretKey; getEncoded() = raw bytes

basics

~10 s

Ask KeyGenerator for an algorithm like AES, call init() with the key size (for example 256 bits), then generateKey(). It returns a SecretKey you use to encrypt and decrypt.

solid answer

~40 s

A symmetric key is one secret used for both encrypting and decrypting. In Java you create it with KeyGenerator.getInstance("AES"), then call init(256) to set the key length in bits, then generateKey() which returns a SecretKey. init() controls the key size and, in its overloads, the source of randomness (a SecureRandom). If you skip init(), the provider falls back to a default size, which may be weaker than you want, so always set it explicitly. The returned SecretKey wraps the raw bytes; you can read them with getEncoded(). KeyGenerator is for symmetric algorithms (AES, HmacSHA256); asymmetric key pairs use a different class, KeyPairGenerator. Reuse one well-seeded SecureRandom rather than creating a new one per call.

code

java · 8 lines
java
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.SecureRandom;

KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(256, new SecureRandom());   // 256-bit AES, explicit CSPRNG
SecretKey key = kg.generateKey();
byte[] raw = key.getEncoded();      // sensitive bytes; handle with care

go deeper

for a junior

Knows the three-call recipe and that it yields a SecretKey for AES.

for a middle

Explains that init controls key size and randomness, knows the valid AES sizes, and that skipping init uses a default.

for a senior

Discusses SecureRandom reuse, getEncoded sensitivity, default-size pitfalls, and chooses KeyGenerator vs SecretKeyFactory correctly.

for a principal

Speaks to provider/FIPS selection, org-wide key-size policy, and avoiding hand-rolled key material.

## What a key is Cryptography turns readable data (plaintext) into scrambled data (ciphertext) using a **key** — a secret number, usually represented as a sequence of bytes. **Symmetric** cryptography uses the *same* key to encrypt and to decrypt (like a single physical key that both locks and unlocks a door). AES (Advanced Encryption Standard) is the standard symmetric cipher. ## The JCA / JCE Java's crypto is the **JCA** (Java Cryptography Architecture) / **JCE** (Java Cryptography Extension): a provider-based framework. You ask for an algorithm *by name* (a String) and a **provider** (a plug-in implementing it) supplies the real code. This is why almost every crypto class is created with a static `getInstance("<algorithm>")` factory instead of a constructor. ## KeyGenerator step by step `javax.crypto.KeyGenerator` produces symmetric keys. 1. `KeyGenerator kg = KeyGenerator.getInstance("AES");` — pick the algorithm. Throws `NoSuchAlgorithmException` if no provider offers it. 2. `kg.init(256);` — set the **key size in bits**. AES allows 128, 192, or 256. There are overloads: `init(int keysize)`, `init(int keysize, SecureRandom)`, and `init(AlgorithmParameterSpec, ...)`. The size argument is the single most security-relevant choice here. 3. `SecretKey key = kg.generateKey();` — produce the key. The bytes come from a **SecureRandom** (a cryptographically strong random source). ## What init() controls `init()` sets (a) the **key length** and (b) optionally the **randomness source**. If you never call `init()`, the provider uses a **default key size**, which historically can be smaller/weaker than you intend — so calling `init` explicitly is a best practice. For HMAC keys (e.g. `"HmacSHA256"`) the size is the MAC key length. ## SecureRandom Keys must be unpredictable. `java.security.SecureRandom` is the CSPRNG (cryptographically secure pseudo-random number generator). The no-arg `SecureRandom()` is fine on modern JDKs (it self-seeds from the OS). Pass it via `init(256, secureRandom)` if you want to control it; reuse one instance rather than constructing one per key. ## SecretKey `generateKey()` returns a `javax.crypto.SecretKey`. `getEncoded()` returns the raw key bytes (a `byte[]`) — useful for storing or wrapping, but treat those bytes as highly sensitive (zero them when done where possible). You then pass the SecretKey to a `Cipher` to actually encrypt/decrypt. ## Contrast with the asymmetric path For public/private **key pairs** (RSA, EC) you use `KeyPairGenerator` (`initialize(...)`, `generateKeyPair()`) instead — a separate class because the shape (a pair, not one key) differs. ## Deriving your answer at any level - Junior: name the three calls (getInstance, init, generateKey) and that it makes a SecretKey. - Senior: add that init controls size + randomness, defaults can be weak, reuse SecureRandom, mention getEncoded sensitivity. - Principal: discuss provider selection, FIPS-validated providers, key-size policy across an org, and not hand-rolling key material.

  • What is the difference between KeyGenerator and SecretKeyFactory?
    KeyGenerator creates brand-new random keys. SecretKeyFactory converts between key representations — e.g. deriving a key from a password with PBKDF2, or turning raw bytes / a KeySpec into a SecretKey object.
  • Does init() take bits or bytes?
    Bits. init(256) means a 256-bit key (32 bytes). Passing 256 expecting bytes would request an invalid/huge AES key.

saying these in an interview costs you the question

  • Calling generateKey() without init() and assuming a safe default size
  • Confusing KeyGenerator (symmetric) with KeyPairGenerator (asymmetric)
  • Passing a byte count instead of a bit count to init (256 bits, not 256 bytes)
  • Creating a new SecureRandom per key instead of reusing one
  • Using new Random() / Math.random() as the randomness source

context

open as a page

How do you generate an asymmetric key pair (e.g. RSA or EC) in Java, and how does it differ from generating a symmetric key?

level: middleimportance: must knowfreq 55%

basics

~10 s

Use KeyPairGenerator: getInstance("RSA"), initialize(2048), generateKeyPair(). You get a KeyPair with a public key (shareable) and a private key (secret). Symmetric uses KeyGenerator and produces one shared SecretKey instead.

open as a page

How do you persist and retrieve keys and certificates using a Java KeyStore, including protection parameters and aliases?

level: middleimportance: must knowfreq 58%

basics

~20 s

A KeyStore is a password-protected file of keys and certificates. You load() it (or load(null) for empty), store entries under a string alias with a password, then save with store(), and read them back with getKey(alias, password) or getCertificate(alias).

open as a page

What role does SecureRandom play in key generation, and what are the pitfalls of seeding it incorrectly?

level: seniorimportance: should knowfreq 45%

basics

~10 s

SecureRandom supplies the unpredictable random bytes that keys are built from. If the randomness is predictable, attackers can guess your keys. Use SecureRandom (a strong generator), never new Random(), and let it self-seed.

open as a page

In production, how would you organize keystores vs truststores and protect private key material — and what are the trade-offs of file-based KeyStores versus an HSM/KMS?

level: principalimportance: should knowfreq 35%

basics

~20 s

Keep your own private keys in a keystore and the certificates you trust in a separate truststore. File-based stores are simple but the key bytes live in process memory; an HSM or cloud KMS keeps keys in hardware so they never leave, at the cost of latency and complexity.

open as a page