KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > maverick > crypto > security > SecureRandom


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.maverick.crypto.security;
21
22
23 import com.maverick.crypto.digests.SHA1Digest;
24
25 /**
26  * An implementation of SecureRandom specifically for the
27  * light-weight API, JDK 1.0, and the J2ME. Random generation is
28  * based on the traditional SHA1 with counter. Calling setSeed
29  * will always increase the entropy of the hash.
30  *
31  * @author Bouncycastle.org
32  */

33 public class SecureRandom
34     extends java.util.Random JavaDoc {
35   private static SecureRandom rand = new SecureRandom();
36
37   private byte[] seed;
38
39   private long counter = 1;
40   private SHA1Digest digest = new SHA1Digest();
41   private byte[] state = new byte[digest.getDigestSize()];
42
43   // public constructors
44
public SecureRandom() {
45     super(0);
46     setSeed(System.currentTimeMillis());
47   }
48
49   public SecureRandom(
50       byte[] inSeed) {
51     setSeed(inSeed);
52   }
53
54   // protected constructors
55
// protected SecureRandom(SecureRandomSpi srs, Provider provider);
56

57   // public class methods
58
public static SecureRandom getInstance(String JavaDoc algorithm) {
59     return new SecureRandom();
60   }
61
62   public static SecureRandom getInstance() {
63     synchronized(rand) {
64       rand.setSeed(System.currentTimeMillis());
65       return rand;
66     }
67   }
68
69   public static byte[] getSeed(
70       int numBytes) {
71     byte[] rv = new byte[numBytes];
72
73     synchronized(rand) {
74       rand.setSeed(System.currentTimeMillis());
75       rand.nextBytes(rv);
76     }
77
78     return rv;
79   }
80
81   // public instance methods
82
public byte[] generateSeed(
83       int numBytes) {
84     byte[] rv = new byte[numBytes];
85
86     nextBytes(rv);
87
88     return rv;
89   }
90
91   // public final Provider getProvider();
92
public synchronized void setSeed(
93       byte[] inSeed) {
94     digest.update(inSeed, 0, inSeed.length);
95   }
96
97   public synchronized void nextBytes(byte[] bytes) {
98     nextBytes(bytes, 0, bytes.length);
99   }
100
101   // public methods overriding random
102
public synchronized void nextBytes(
103       byte[] bytes, int offset, int length) {
104     int stateOff = 0;
105
106     digest.doFinal(state, 0);
107
108     for (int i = 0; i != length; i++) {
109       if (stateOff == state.length) {
110         byte[] b = longToBytes(counter++);
111
112         digest.update(b, 0, b.length);
113         digest.update(state, 0, state.length);
114         digest.doFinal(state, 0);
115         stateOff = 0;
116       }
117       bytes[i + offset] = state[stateOff++];
118     }
119
120     byte[] b = longToBytes(counter++);
121
122     digest.update(b, 0, b.length);
123     digest.update(state, 0, state.length);
124   }
125
126   public synchronized void setSeed(
127       long rSeed) {
128     if (rSeed != 0) {
129       setSeed(longToBytes(rSeed));
130     }
131   }
132
133   private byte[] intBytes = new byte[4];
134
135   public synchronized int nextInt() {
136     nextBytes(intBytes);
137
138     int result = 0;
139
140     for (int i = 0; i < 4; i++) {
141       result = (result << 8) + (intBytes[i] & 0xff);
142     }
143
144     return result;
145   }
146
147   protected final synchronized int next(
148       int numBits) {
149     int size = (numBits + 7) / 8;
150     byte[] bytes = new byte[size];
151
152     nextBytes(bytes);
153
154     int result = 0;
155
156     for (int i = 0; i < size; i++) {
157       result = (result << 8) + (bytes[i] & 0xff);
158     }
159
160     return result & ( (1 << numBits) - 1);
161   }
162
163   private byte[] longBytes = new byte[8];
164
165   private synchronized byte[] longToBytes(
166       long val) {
167     for (int i = 0; i != 8; i++) {
168       longBytes[i] = (byte) val;
169       val >>>= 8;
170     }
171
172     return longBytes;
173   }
174 }
175
Popular Tags