javaintermediate
Secure Password Hashing
Hash passwords securely with PBKDF2 and verify them — no external libraries required.
javaPress ⌘/Ctrl + Shift + C to copy
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
public class PasswordHasher {
private static final int ITERATIONS = 100_000;
private static final int KEY_LENGTH = 256;
private static final int SALT_LENGTH = 16;
private static final String ALGORITHM = "PBKDF2WithHmacSHA256";
// Hash a password → returns "iterations:salt:hash" (all Base64)
public static String hash(String password) {
byte[] salt = new byte[SALT_LENGTH];
new SecureRandom().nextBytes(salt);
byte[] hash = pbkdf2(password.toCharArray(), salt, ITERATIONS, KEY_LENGTH);
return ITERATIONS + ":" +
Base64.getEncoder().encodeToString(salt) + ":" +
Base64.getEncoder().encodeToString(hash);
}
// Verify password against stored hash
public static boolean verify(String password, String stored) {
String[] parts = stored.split(":");
if (parts.length != 3) return false;
int iterations = Integer.parseInt(parts[0]);
byte[] salt = Base64.getDecoder().decode(parts[1]);
byte[] expectedHash = Base64.getDecoder().decode(parts[2]);
byte[] actualHash = pbkdf2(password.toCharArray(), salt, iterations, expectedHash.length * 8);
return slowEquals(expectedHash, actualHash);
}
// Constant-time comparison (prevents timing attacks)
private static boolean slowEquals(byte[] a, byte[] b) {
if (a.length != b.length) return false;
int diff = 0;
for (int i = 0; i < a.length; i++) {
diff |= a[i] ^ b[i];
}
return diff == 0;
}
private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int keyLength) {
try {
PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, keyLength);
SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
return factory.generateSecret(spec).getEncoded();
} catch (Exception e) {
throw new RuntimeException("PBKDF2 failed", e);
}
}
public static void main(String[] args) {
String password = "mySecurePass123";
// Hash
String hashed = hash(password);
System.out.println("Stored: " + hashed);
// Verify (correct)
System.out.println("Valid: " + verify(password, hashed)); // true
System.out.println("Wrong: " + verify("wrongPass", hashed)); // false
// Each hash is unique (different salt)
System.out.println(hash(password)); // different from above
}
}Use Cases
- User registration password storage
- Secure credential verification
- Password-based key derivation
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
javaadvanced
Spring Security — JWT Authentication
Implement JWT authentication with Spring Security: token generation, validation, and filter chain.
Best for: Securing REST APIs with JWT tokens
#spring-boot#jwt
javaadvanced
AES Encryption and Decryption
Encrypt and decrypt data with AES-GCM in Java: key generation, secure random IV, and Base64 encoding.
Best for: Encrypting sensitive data at rest
#java#encryption
typescriptbeginner
Bcrypt Password Hash & Verify
Hash and verify passwords with bcrypt using configurable salt rounds and timing-safe comparison.
Best for: User registration
#bcrypt#password
typescriptintermediate
Node.js Crypto Utility Functions
Common cryptographic operations: hashing, HMAC, encryption, random tokens, and password hashing.
Best for: Secure password storage and verification
#nodejs#crypto