How do you generate a symmetric secret key in Java using KeyGenerator, and what does init() control?
answer
- getInstance -> init(size) -> generateKey
- KeyGenerator = symmetric (AES, HMAC)
- init sets bit-length + SecureRandom
- skip init = provider default (can be weak)
- returns SecretKey; getEncoded() = raw bytes
basics
~10 sAsk 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 sA 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 linesimport 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 carego deeper
Knows the three-call recipe and that it yields a SecretKey for AES.
Explains that init controls key size and randomness, knows the valid AES sizes, and that skipping init uses a default.
Discusses SecureRandom reuse, getEncoded sensitivity, default-size pitfalls, and chooses KeyGenerator vs SecretKeyFactory correctly.
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