本文目录导读:

我为您提供几个Java中使用SecureRandom的实用案例,涵盖不同场景。
基础使用 - 生成随机数
import java.security.SecureRandom;
public class BasicSecureRandom {
public static void main(String[] args) {
// 创建SecureRandom实例
SecureRandom secureRandom = new SecureRandom();
// 生成随机整数
int randomInt = secureRandom.nextInt();
System.out.println("随机整数: " + randomInt);
// 生成0-99的随机数
int randomRange = secureRandom.nextInt(100);
System.out.println("0-99的随机数: " + randomRange);
// 生成随机长整数
long randomLong = secureRandom.nextLong();
System.out.println("随机长整数: " + randomLong);
// 生成随机布尔值
boolean randomBoolean = secureRandom.nextBoolean();
System.out.println("随机布尔值: " + randomBoolean);
// 生成随机浮点数 (0.0 - 1.0)
float randomFloat = secureRandom.nextFloat();
System.out.println("随机浮点数: " + randomFloat);
// 生成随机双精度浮点数 (0.0 - 1.0)
double randomDouble = secureRandom.nextDouble();
System.out.println("随机双精度浮点数: " + randomDouble);
}
}
生成随机密码
import java.security.SecureRandom;
public class RandomPasswordGenerator {
private static final String CHAR_LOWER = "abcdefghijklmnopqrstuvwxyz";
private static final String CHAR_UPPER = CHAR_LOWER.toUpperCase();
private static final String NUMBER = "0123456789";
private static final String OTHER_CHAR = "!@#$%^&*()-_=+[]{};:,.?";
private static final String PASSWORD_ALLOW_BASE = CHAR_LOWER + CHAR_UPPER + NUMBER + OTHER_CHAR;
private static final SecureRandom RANDOM = new SecureRandom();
public static String generateRandomPassword(int length) {
if (length < 4) {
throw new IllegalArgumentException("密码长度至少为4位");
}
StringBuilder sb = new StringBuilder(length);
// 确保密码包含至少一种字符类型
sb.append(getRandomChar(CHAR_LOWER));
sb.append(getRandomChar(CHAR_UPPER));
sb.append(getRandomChar(NUMBER));
sb.append(getRandomChar(OTHER_CHAR));
// 填充剩余长度
for (int i = 4; i < length; i++) {
sb.append(getRandomChar(PASSWORD_ALLOW_BASE));
}
// 使用Fisher-Yates算法打乱顺序
String password = sb.toString();
char[] passwordArray = password.toCharArray();
for (int i = passwordArray.length - 1; i > 0; i--) {
int j = RANDOM.nextInt(i + 1);
char temp = passwordArray[i];
passwordArray[i] = passwordArray[j];
passwordArray[j] = temp;
}
return new String(passwordArray);
}
private static char getRandomChar(String source) {
int index = RANDOM.nextInt(source.length());
return source.charAt(index);
}
public static void main(String[] args) {
// 生成10个不同的16位密码
for (int i = 0; i < 10; i++) {
System.out.println("密码 " + (i + 1) + ": " + generateRandomPassword(16));
}
}
}
生成随机令牌/会话ID
import java.security.SecureRandom;
import java.util.Base64;
public class TokenGenerator {
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
// 生成Base64编码的随机令牌
public static String generateBase64Token(int byteLength) {
byte[] bytes = new byte[byteLength];
SECURE_RANDOM.nextBytes(bytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}
// 生成十六进制随机令牌
public static String generateHexToken(int byteLength) {
byte[] bytes = new byte[byteLength];
SECURE_RANDOM.nextBytes(bytes);
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
// 生成数字一次性密码 (OTP)
public static String generateOTP(int length) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(SECURE_RANDOM.nextInt(10));
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println("Base64 Token (32 bytes): " + generateBase64Token(32));
System.out.println("Hex Token (16 bytes): " + generateHexToken(16));
System.out.println("6位OTP: " + generateOTP(6));
System.out.println("8位OTP: " + generateOTP(8));
}
}
文件加密密钥生成
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
public class EncryptionKeyGenerator {
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
// 使用SecureRandom生成AES密钥
public static SecretKey generateAESKey(int keySize) throws NoSuchAlgorithmException {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(keySize, SECURE_RANDOM);
return keyGen.generateKey();
}
// 使用SecureRandom生成随机密钥(任意算法)
public static byte[] generateRandomKey(int keySize) {
byte[] key = new byte[keySize / 8];
SECURE_RANDOM.nextBytes(key);
return key;
}
// 生成AES密钥并转换为Base64字符串
public static String generateAESKeyBase64(int keySize) throws NoSuchAlgorithmException {
SecretKey key = generateAESKey(keySize);
return Base64.getEncoder().encodeToString(key.getEncoded());
}
public static void main(String[] args) {
try {
// 生成128位AES密钥
System.out.println("AES-128密钥 (Base64): " + generateAESKeyBase64(128));
// 生成256位AES密钥
System.out.println("AES-256密钥 (Base64): " + generateAESKeyBase64(256));
// 生成32字节随机密钥(256位)
byte[] keyBytes = generateRandomKey(256);
System.out.println("Hmac密钥 (Hex): " + bytesToHex(keyBytes));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
线程安全的SecureRandom单例
import java.security.SecureRandom;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ThreadSafeSecureRandom {
// 使用ThreadLocal确保每个线程有自己的SecureRandom实例
private static final ThreadLocal<SecureRandom> THREAD_LOCAL =
ThreadLocal.withInitial(SecureRandom::new);
// 或者使用静态实例(SecureRandom本身是线程安全的)
private static final SecureRandom SHARED_RANDOM = new SecureRandom();
public static int getRandomInt(int bound) {
// 使用ThreadLocal版本
return THREAD_LOCAL.get().nextInt(bound);
}
public static String getRandomToken(int bytes) {
// 使用共享实例
byte[] token = new byte[bytes];
SHARED_RANDOM.nextBytes(token);
return bytesToHex(token);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
final int taskId = i;
executor.submit(() -> {
int random = getRandomInt(1000);
String token = getRandomToken(16);
System.out.println("任务 " + taskId + " - 随机数: " + random + ", Token: " + token);
});
}
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
}
}
防碰撞的唯一ID生成器
import java.security.SecureRandom;
import java.time.Instant;
public class SecureIdGenerator {
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
/**
* 生成UUID (版本4)
*/
public static String generateUUID() {
byte[] randomBytes = new byte[16];
SECURE_RANDOM.nextBytes(randomBytes);
// 设置版本为4
randomBytes[6] &= 0x0f;
randomBytes[6] |= 0x40;
// 设置变体
randomBytes[8] &= 0x3f;
randomBytes[8] |= 0x80;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < randomBytes.length; i++) {
if (i == 4 || i == 6 || i == 8 || i == 10) {
sb.append('-');
}
sb.append(String.format("%02x", randomBytes[i]));
}
return sb.toString();
}
/**
* 生成带时间戳的唯一ID
*/
public static String generateTimestampId() {
long timestamp = Instant.now().toEpochMilli();
byte[] randomBytes = new byte[8];
SECURE_RANDOM.nextBytes(randomBytes);
return String.format("%d-%s", timestamp, bytesToHex(randomBytes));
}
/**
* 生成雪花算法风格的ID
*/
public static long generateSnowflakeId() {
long timestamp = System.currentTimeMillis() << 22;
long randomPart = (long)(SECURE_RANDOM.nextDouble() * (1 << 22));
return timestamp + randomPart;
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println("UUID v4: " + generateUUID());
System.out.println("时间戳ID: " + generateTimestampId());
// 生成多个ID验证唯一性
for (int i = 0; i < 5; i++) {
System.out.println("雪花ID " + (i + 1) + ": " + generateSnowflakeId());
}
}
}
关键要点
- 安全性:
SecureRandom基于密码学安全算法,适合安全敏感场景 - 线程安全:
SecureRandom实例是线程安全的,可以共享使用 - 性能:首次初始化可能较慢,但后续操作性能良好
- 选择建议:
- 一般场景:
new SecureRandom() - 高性能系统:使用
ThreadLocal<SecureRandom> - 安全关键用途:考虑显式指定算法(如
SHA1PRNG或NativePRNG)
- 一般场景:
这些案例覆盖了大多数实际应用场景,您可以根据具体需求选择适合的实现。