Welcome to mirror list, hosted at ThFree Co, Russian Federation.

SecureRandom.java « security « java « j2me « main « src « core - gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 13ffde9b7a2318ff5bff3ac993484b4ad707c413 (plain)
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
package java.security;

import java.util.Random;

import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.prng.RandomGenerator;
import org.bouncycastle.crypto.prng.DigestRandomGenerator;

/**
 * An implementation of SecureRandom specifically for the light-weight API, JDK
 * 1.0, and the J2ME. Random generation is based on the traditional SHA1 with
 * counter. Calling setSeed will always increase the entropy of the hash.
 * <p>
 * <b>Do not use this class without calling setSeed at least once</b>! There
 * are some example seed generators in the org.bouncycastle.prng package.
 */
public class SecureRandom extends java.util.Random
{
    // Note: all objects of this class should be deriving their random data from
    // a single generator appropriate to the digest being used.
    private static final RandomGenerator sha1Generator = new DigestRandomGenerator(new SHA1Digest());
    private static final RandomGenerator sha256Generator = new DigestRandomGenerator(new SHA256Digest());

    protected RandomGenerator             generator;

    // public constructors
    public SecureRandom()
    {
        this(sha1Generator);
        setSeed(System.currentTimeMillis());
    }

    public SecureRandom(byte[] inSeed)
    {
        this(sha1Generator);
        setSeed(inSeed);
    }

    protected SecureRandom(
        RandomGenerator generator)
    {
        super(0);
        this.generator = generator;
    }

    // protected constructors
    // protected SecureRandom(SecureRandomSpi srs, Provider provider);

    // public class methods
    public static SecureRandom getInstance(String algorithm)
    {
        if (algorithm.equals("SHA1PRNG"))
        {
            return new SecureRandom(sha1Generator);
        }
        if (algorithm.equals("SHA256PRNG"))
        {
            return new SecureRandom(sha256Generator);
        }
        return new SecureRandom();    // follow old behaviour
    }

    public static SecureRandom getInstance(String algorithm, String provider)
    {
        return getInstance(algorithm);
    }

    public static byte[] getSeed(int numBytes)
    {
        byte[] rv = new byte[numBytes];

        sha1Generator.addSeedMaterial(System.currentTimeMillis());
        sha1Generator.nextBytes(rv);

        return rv;
    }

    // public instance methods
    public byte[] generateSeed(int numBytes)
    {
        byte[] rv = new byte[numBytes];

        nextBytes(rv);

        return rv;
    }

    // public final Provider getProvider();
    public void setSeed(byte[] inSeed)
    {
        generator.addSeedMaterial(inSeed);
    }

    // public methods overriding random
    public void nextBytes(byte[] bytes)
    {
        generator.nextBytes(bytes);
    }

    public void setSeed(long rSeed)
    {
        if (rSeed != 0)    // to avoid problems with Random calling setSeed in construction
        {
            generator.addSeedMaterial(rSeed);
        }
    }

    public int nextInt()
    {
        byte[] intBytes = new byte[4];

        nextBytes(intBytes);

        int result = 0;

        for (int i = 0; i < 4; i++)
        {
            result = (result << 8) + (intBytes[i] & 0xff);
        }

        return result;
    }

    protected final int next(int numBits)
    {
        int size = (numBits + 7) / 8;
        byte[] bytes = new byte[size];

        nextBytes(bytes);

        int result = 0;

        for (int i = 0; i < size; i++)
        {
            result = (result << 8) + (bytes[i] & 0xff);
        }

        return result & ((1 << numBits) - 1);
    }
}