jeudi 4 janvier 2018

Can it be that java SecureRandom is not that random?

Look at the code below, I am generating 1024 blocks of 1024 random bytes. It's about a million random numbers, but yet there is a clear pattern in it.

SecureRandom random = new SecureRandom();

int[] bytes = new int[256];
byte[] buffer = new byte[1024];
byte[] buffer2 = new byte[1024];
Random random2 = new Random(123456);
for (int i = 0; i < 1024; i++) {
    random.nextBytes(buffer);
    random2.nextBytes(buffer2);
    for (int j = 0; j < buffer.length; j++) {
        byte b = (byte) (buffer[i] + buffer2[i]);
        bytes[b & 0xFF]++;
    }
}

Arrays.sort(bytes);
for (int i = 0; i < bytes.length; i++) {
    System.out.println(i + " " + bytes[i]);
}

Note that new Random(123456); means that it will always produce the same output. 123456 is the hardcoded seed.

And the output is:

0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 1024
9 1024
10 1024
11 1024
12 1024
13 1024
14 1024
15 1024
16 1024
17 1024
18 1024
19 1024
20 1024
21 1024
22 1024
23 1024
24 1024
25 1024
26 2048
27 2048
28 2048
29 2048
30 2048
31 2048
32 2048
33 2048
34 2048
35 2048
36 2048
37 2048
38 2048
39 2048
40 2048
41 2048
42 2048
43 2048
44 2048
45 2048
46 2048
47 2048
48 2048
49 2048
50 2048
51 2048
52 2048
53 2048
54 2048
55 2048
56 2048
57 2048
58 2048
59 2048
60 2048
61 2048
62 3072
63 3072
64 3072
65 3072
66 3072
67 3072
68 3072
69 3072
70 3072
71 3072
72 3072
73 3072
74 3072
75 3072
76 3072
77 3072
78 3072
79 3072
80 3072
81 3072
82 3072
83 3072
84 3072
85 3072
86 3072
87 3072
88 3072
89 3072
90 3072
91 3072
92 3072
93 3072
94 3072
95 3072
96 3072
97 3072
98 3072
99 3072
100 3072
101 3072
102 3072
103 3072
104 3072
105 3072
106 3072
107 3072
108 3072
109 4096
110 4096
111 4096
112 4096
113 4096
114 4096
115 4096
116 4096
117 4096
118 4096
119 4096
120 4096
121 4096
122 4096
123 4096
124 4096
125 4096
126 4096
127 4096
128 4096
129 4096
130 4096
131 4096
132 4096
133 4096
134 4096
135 4096
136 4096
137 4096
138 4096
139 4096
140 4096
141 4096
142 4096
143 4096
144 4096
145 4096
146 4096
147 4096
148 4096
149 4096
150 4096
151 4096
152 4096
153 4096
154 4096
155 4096
156 4096
157 4096
158 4096
159 4096
160 4096
161 4096
162 5120
163 5120
164 5120
165 5120
166 5120
167 5120
168 5120
169 5120
170 5120
171 5120
172 5120
173 5120
174 5120
175 5120
176 5120
177 5120
178 5120
179 5120
180 5120
181 5120
182 5120
183 5120
184 5120
185 5120
186 5120
187 5120
188 5120
189 5120
190 5120
191 5120
192 5120
193 5120
194 5120
195 5120
196 5120
197 5120
198 6144
199 6144
200 6144
201 6144
202 6144
203 6144
204 6144
205 6144
206 6144
207 6144
208 6144
209 6144
210 6144
211 6144
212 6144
213 6144
214 6144
215 6144
216 6144
217 6144
218 6144
219 6144
220 6144
221 6144
222 6144
223 6144
224 6144
225 6144
226 6144
227 6144
228 7168
229 7168
230 7168
231 7168
232 7168
233 7168
234 7168
235 7168
236 7168
237 7168
238 7168
239 7168
240 7168
241 7168
242 8192
243 8192
244 8192
245 8192
246 8192
247 8192
248 8192
249 8192
250 9216
251 9216
252 9216
253 10240
254 11264
255 11264

If you run this code multiple times, you will get similar patterns in each run while 0-7 is always 0. If you try to count the byte values that you are getting and try to apply to this pattern, very fast you will be able to make guesses to what the next value should be, quite accurately.

So is this code example is enough to show that it's indeed a security vulnerability in SecureRandom, or I missed something?




Aucun commentaire:

Enregistrer un commentaire