-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Expand file tree
/
Copy pathPrngTest.java
More file actions
156 lines (146 loc) · 5.93 KB
/
Copy pathPrngTest.java
File metadata and controls
156 lines (146 loc) · 5.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package com.example.crypto.algorithms;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;
import javax.crypto.SecretKey;
import javax.crypto.KeyGenerator;
/**
* PrngTest demonstrates various approaches for generating random data using
* PRNG/RNG APIs.
*
* It covers: 1) Secure random generation using SecureRandom (default and
* getInstanceStrong). 2) Insecure random generation using java.util.Random. 3)
* Flawed PRNG usage by setting a fixed seed. 4) Dynamic PRNG selection based on
* configuration. 5) Usage of random data as nonces/IVs in symmetric encryption.
*
* SAST/CBOM Notes: - SecureRandom (and SecureRandom.getInstanceStrong) are
* recommended. - java.util.Random is not suitable for cryptographic purposes. -
* Re-seeding or using a fixed seed with SecureRandom makes it predictable. -
* IVs and nonces must be unique for each operation; reusing fixed values is
* insecure.
*/
public class PrngTest {
// ---------- Secure Random Generation ----------
/**
* Generates random bytes using the default SecureRandom. SAST: SecureRandom
* is recommended for cryptographically secure random data.
*
* @param numBytes Number of bytes to generate.
* @return A byte array of random data.
*/
public byte[] generateSecureRandomBytes(int numBytes) {
SecureRandom secureRandom = new SecureRandom();
byte[] bytes = new byte[numBytes];
secureRandom.nextBytes(bytes);
return bytes;
}
/**
* Generates random bytes using SecureRandom.getInstanceStrong(). SAST:
* getInstanceStrong() returns a strong RNG (may block in some
* environments).
*
* @param numBytes Number of bytes to generate.
* @return A byte array of random data.
* @throws NoSuchAlgorithmException if a strong RNG is not available.
*/
public byte[] generateSecureRandomBytesStrong(int numBytes) throws NoSuchAlgorithmException {
SecureRandom secureRandom = SecureRandom.getInstanceStrong();
byte[] bytes = new byte[numBytes];
secureRandom.nextBytes(bytes);
return bytes;
}
// ---------- Insecure Random Generation ----------
/**
* Generates random bytes using java.util.Random. SAST: java.util.Random is
* predictable and insecure for cryptographic purposes.
*
* @param numBytes Number of bytes to generate.
* @return A byte array of random data.
*/
public byte[] generateInsecureRandomBytes(int numBytes) {
Random random = new Random();
byte[] bytes = new byte[numBytes];
random.nextBytes(bytes);
return bytes;
}
/**
* Generates random bytes using SecureRandom with a fixed seed. SAST: Fixed
* seeding makes SecureRandom predictable and insecure.
*
* @param numBytes Number of bytes to generate.
* @return A byte array of predictable random data.
*/
public byte[] generatePredictableRandomBytes(int numBytes) {
SecureRandom secureRandom = new SecureRandom();
// Fixed seed (predictable and insecure)
secureRandom.setSeed(0xDEADBEEF);
byte[] bytes = new byte[numBytes];
secureRandom.nextBytes(bytes);
return bytes;
}
// ---------- Dynamic PRNG Selection ----------
/**
* Dynamically selects a PRNG algorithm based on a configuration property.
* If the algorithm is unknown, falls back to java.util.Random (insecure).
* SAST: Dynamic selection may introduce risk if an insecure RNG is chosen.
*
* @param algorithmName The PRNG algorithm name (e.g. "SHA1PRNG",
* "NativePRNGNonBlocking", "getInstanceStrong").
* @param numBytes Number of bytes to generate.
* @return A byte array of random data.
* @throws NoSuchAlgorithmException if the algorithm is not available.
*/
public byte[] dynamicRandomGeneration(String algorithmName, int numBytes) throws NoSuchAlgorithmException {
SecureRandom secureRandom;
if ("SHA1PRNG".equalsIgnoreCase(algorithmName)) {
// SHA1PRNG is older and less preferred.
secureRandom = SecureRandom.getInstance("SHA1PRNG");
} else if ("NativePRNGNonBlocking".equalsIgnoreCase(algorithmName)) {
secureRandom = SecureRandom.getInstance("NativePRNGNonBlocking");
} else if ("getInstanceStrong".equalsIgnoreCase(algorithmName)) {
secureRandom = SecureRandom.getInstanceStrong();
} else {
// Fallback to insecure java.util.Random.
Random random = new Random();
byte[] bytes = new byte[numBytes];
random.nextBytes(bytes);
return bytes;
}
byte[] bytes = new byte[numBytes];
secureRandom.nextBytes(bytes);
return bytes;
}
// ---------- Usage Examples: Nonce/IV Generation for Symmetric Encryption
// ----------
/**
* Demonstrates secure generation of an IV for AES-GCM encryption. SAST: A
* unique, random IV is required for each encryption operation.
*
* @return A 12-byte IV.
*/
public byte[] generateRandomIVForGCM() {
return generateSecureRandomBytes(12);
}
/**
* Demonstrates insecure use of a fixed IV for AES-GCM encryption. SAST:
* Reusing a fixed IV in AES-GCM compromises security.
*
* @return A fixed 12-byte IV (all zeros).
*/
public byte[] generateFixedIVForGCM() {
return new byte[12]; // 12 bytes of zeros.
}
// ---------- Example: Using PRNG for Key Generation ----------
/**
* Generates a secure 256-bit AES key using SecureRandom. SAST: Strong key
* generation is critical for symmetric cryptography.
*
* @return A new AES SecretKey.
* @throws Exception if key generation fails.
*/
public SecretKey generateAESKey() throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256, new SecureRandom());
return keyGen.generateKey();
}
}