@@ -0,0 +1,3561 @@
+package com.warrenstrange.googleauth;%0A%0Aimport java.security.NoSuchAlgorithmException;%0Aimport java.security.NoSuchProviderException;%0Aimport java.security.SecureRandom;%0Aimport java.util.concurrent.atomic.AtomicInteger;%0Aimport java.util.concurrent.locks.Lock;%0Aimport java.util.concurrent.locks.ReentrantReadWriteLock;%0A%0A/**%0A * Date: 08/04/14%0A * Time: 15:21%0A *%0A * @author Enrico M. Crisostomo%0A */%0Aclass ReseedingSecureRandom %7B%0A    private static final int MAX_OPERATIONS = 1_000_000;%0A    private final String provider;%0A    private final String algorithm;%0A    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();%0A    private final Lock readLock = lock.readLock();%0A    private final Lock writeLock = lock.writeLock();%0A    private final AtomicInteger count = new AtomicInteger(0);%0A    private SecureRandom secureRandom;%0A%0A    ReseedingSecureRandom() %7B%0A        this.algorithm = null;%0A        this.provider = null;%0A%0A        buildSecureRandom();%0A    %7D%0A%0A    ReseedingSecureRandom(String algorithm) %7B%0A        if (algorithm == null) %7B%0A            throw new IllegalArgumentException(%22Algorithm cannot be null.%22);%0A        %7D%0A%0A        this.algorithm = algorithm;%0A        this.provider = null;%0A%0A        buildSecureRandom();%0A    %7D%0A%0A    ReseedingSecureRandom(String algorithm, String provider) %7B%0A        if (algorithm == null) %7B%0A            throw new IllegalArgumentException(%22Algorithm cannot be null.%22);%0A        %7D%0A%0A        if (provider == null) %7B%0A            throw new IllegalArgumentException(%22Provider cannot be null.%22);%0A        %7D%0A%0A        this.algorithm = algorithm;%0A        this.provider = provider;%0A%0A        buildSecureRandom();%0A    %7D%0A%0A    private void buildSecureRandom() %7B%0A        try %7B%0A            System.out.println(%22Building secure random instance: %22 + count.get());%0A            if (this.algorithm == null && this.provider == null) %7B%0A                this.secureRandom = new SecureRandom();%0A            %7D else if (this.provider == null) %7B%0A                this.secureRandom = SecureRandom.getInstance(this.algorithm);%0A            %7D else %7B%0A                this.secureRandom = SecureRandom.getInstance(this.algorithm, this.provider);%0A            %7D%0A        %7D catch (NoSuchAlgorithmException e) %7B%0A            throw new GoogleAuthenticatorException(%0A                    String.format(%0A                            %22Could not initialise SecureRandom %22 +%0A                                    %22with the specified algorithm: %25s%22,%0A                            this.algorithm%0A                    ), e%0A            );%0A        %7D catch (NoSuchProviderException e) %7B%0A            throw new GoogleAuthenticatorException(%0A                    String.format(%0A                            %22Could not initialise SecureRandom %22 +%0A                                    %22with the specified provider: %25s%22,%0A                            this.provider%0A                    ), e%0A            );%0A        %7D%0A    %7D%0A%0A    void nextBytes(byte%5B%5D bytes) %7B%0A        readLock.lock();%0A%0A        int currentCount = count.incrementAndGet();%0A%0A        if (currentCount %3E MAX_OPERATIONS) %7B%0A            readLock.unlock();%0A            writeLock.lock();%0A%0A            try %7B%0A                currentCount = count.get();%0A%0A                if (currentCount %3E MAX_OPERATIONS) %7B%0A                    buildSecureRandom();%0A                    count.set(0);%0A                %7D%0A%0A                readLock.lock();%0A            %7D finally %7B%0A                writeLock.unlock();%0A            %7D%0A        %7D%0A%0A        try %7B%0A            this.secureRandom.nextBytes(bytes);%0A        %7D finally %7B%0A            readLock.unlock();%0A        %7D%0A    %7D%0A%7D%0A

Add class wrapping a SecureRandom instance which is recreated after a certain number of operations are performed.