1 19 20 package com.maverick.crypto.security; 21 22 23 import com.maverick.crypto.digests.SHA1Digest; 24 25 33 public class SecureRandom 34 extends java.util.Random { 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 SecureRandom() { 45 super(0); 46 setSeed(System.currentTimeMillis()); 47 } 48 49 public SecureRandom( 50 byte[] inSeed) { 51 setSeed(inSeed); 52 } 53 54 57 public static SecureRandom getInstance(String 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 byte[] generateSeed( 83 int numBytes) { 84 byte[] rv = new byte[numBytes]; 85 86 nextBytes(rv); 87 88 return rv; 89 } 90 91 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 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 |