Java8 SecureRandom

Random

java.util.Random 其實一點也不 Random, 因為屬於一種線性分佈,
線性不比離散, 所以就是有公式可以預測啦~

大神的論文在 這裡

https://stackoverflow.com/questions/11051205/difference-between-java-util-random-and-java-security-securerandom

The standard Oracle JDK 7 implementation uses what's called a Linear Congruential Generator to produce random values in java.util.Random.

Predictability of Linear Congruential Generators

Hugo Krawczyk wrote a pretty good paper about how these LCGs can be predicted ("How to predict congruential generators"). If you're lucky and interested, you may still find a free, downloadable version of it on the web. And there's plenty more research that clearly shows that you should never use an LCG for security-critical purposes. This also means that your random numbers are predictable right now, something you don't want for session IDs and the like.

隨機數安全議題

http://wps2015.org/drops/drops/%E8%81%8A%E4%B8%80%E8%81%8A%E9%9A%8F%E6%9C%BA%E6%95%B0%E5%AE%89%E5%85%A8.html

SecureRandom

較推薦的做法是採用 java.security.SecureRandom,


寫個簡單的 Faker


import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * Created by jerry on 2017/11/1.
 */
public class Faker {

    private SecureRandom random;
    
    public Faker() throws NoSuchAlgorithmException {
        this.random = SecureRandom.getInstance("SHA1PRNG");
    }
    
   /**
     * Generate a random alpha numbs.
     *
     * @param length
     * @return
     */
    public String randomAlphaNums(int length) {
        final char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray();
        final String result = IntStream.range(0, length)
                .boxed()
                .map(index -> {
                    char character = chars[random.nextInt(chars.length)];
                    return String.valueOf(character);
                }).collect(Collectors.joining());

        return result;
    }

   /**
     * Generate a uuid.
     *
     * @return
     */
    public String uuid() {
        return UUID.randomUUID().toString();
    }

    /**
     * Generate a fake url
     *
     * @param domain
     * @return
     */
    public String randomUrl(String domain) {
        return new StringBuilder("https://")
                .append(domain)
                .append("/" + randomAlphaNums(5))
                .append("/" + randomAlphaNums(5))
                .toString();
    }
}


@Test
public void testAlphaNumbs() throws NoSuchAlgorithmException {
    Faker faker = new Faker();
    
    // mO03nYMKAiQi06sleVgeQSP4ZWpD5O2sr4M9PXyj6GBA0VHY2ucS9J0s4atRSRovI0EjffBoqBFL3loaLrbpKrxlkHFDHs76nMzW
    System.out.println(faker.randomAlphaNums(100));

    // https://my.domain/KMr1n/3xTIn
    System.out.println(faker.randomUrl("my.domain"));

    // 0b256f71-77bf-4dfb-8fae-850a128c785b
    System.out.println(faker.uuid());
}

題外話 Java Faker

Java Faker 是一款改寫自 Ruby's stympy/faker gem 的小工具, 在 TDD 階段還算滿實用的.



沒有留言:

張貼留言