// Path: commons-base/commons-crypto/src/main/java/ch/ge/ve/commons/crypto/exceptions/CryptoConfigurationRuntimeException.java
// public class CryptoConfigurationRuntimeException extends RuntimeException {
// 
//     public CryptoConfigurationRuntimeException(String message) {
//         super(message);
//     }
// 
//     public CryptoConfigurationRuntimeException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }


import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import ch.ge.ve.commons.crypto.exceptions.CryptoConfigurationRuntimeException;
package ch.ge.ve.commons.crypto.utils;

/*-
 * #%L
 * Common crypto utilities
 * %%
 * Copyright (C) 2015 - 2016 République et Canton de Genève
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */



/**
 * This class provides the centralized way of creating Secure Random Number Generator instances.
 * <p/>
 * The goal is to create SecureRandoms that specify their algorithm and implementation provider, so that
 * the system behaves consistently whichever is the target operation system and jdk:
 * <ul>
 * <li>should not the implementation provider be provided, the OS native one could be used, and we do not want it</li>
 * <li>should not the algorithm provider be provided, the default one of the jdk could be used, and we do not want it</li>
 * </ul>
 * <p/>
 * As a secure coding rule, the direct creation of Random or SecureRandom is prohibited throughout the application.
 */
public class SecureRandomFactory {
    // Mask default constructor, this class shouldn't be instantiated
    private SecureRandomFactory() {}

    /**
     * Important notice from the SecureRandom javadoc:
     * <p>The returned SecureRandom object has not been seeded. To seed the
     * returned object, call the <code>setSeed</code> method.
     * If <code>setSeed</code> is not called, the first call to
     * <code>nextBytes</code> will force the SecureRandom object to seed itself.
     * This self-seeding will not occur if <code>setSeed</code> was
     * previously called.</p>
     *
     * @return a new, not already seeded, Pseudo Random Number Generator instance.
     */
    public static SecureRandom createPRNG() {
        try {
            return SecureRandom.getInstance("SHA1PRNG", "SUN");
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
// Path: commons-base/commons-crypto/src/main/java/ch/ge/ve/commons/crypto/exceptions/CryptoConfigurationRuntimeException.java
// public class CryptoConfigurationRuntimeException extends RuntimeException {
// 
//     public CryptoConfigurationRuntimeException(String message) {
//         super(message);
//     }
// 
//     public CryptoConfigurationRuntimeException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }


// Path: commons-base/commons-crypto/src/main/java/ch/ge/ve/commons/crypto/utils/SecureRandomFactory.java
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import ch.ge.ve.commons.crypto.exceptions.CryptoConfigurationRuntimeException;

package ch.ge.ve.commons.crypto.utils;

/*-
 * #%L
 * Common crypto utilities
 * %%
 * Copyright (C) 2015 - 2016 République et Canton de Genève
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */



/**
 * This class provides the centralized way of creating Secure Random Number Generator instances.
 * <p/>
 * The goal is to create SecureRandoms that specify their algorithm and implementation provider, so that
 * the system behaves consistently whichever is the target operation system and jdk:
 * <ul>
 * <li>should not the implementation provider be provided, the OS native one could be used, and we do not want it</li>
 * <li>should not the algorithm provider be provided, the default one of the jdk could be used, and we do not want it</li>
 * </ul>
 * <p/>
 * As a secure coding rule, the direct creation of Random or SecureRandom is prohibited throughout the application.
 */
public class SecureRandomFactory {
    // Mask default constructor, this class shouldn't be instantiated
    private SecureRandomFactory() {}

    /**
     * Important notice from the SecureRandom javadoc:
     * <p>The returned SecureRandom object has not been seeded. To seed the
     * returned object, call the <code>setSeed</code> method.
     * If <code>setSeed</code> is not called, the first call to
     * <code>nextBytes</code> will force the SecureRandom object to seed itself.
     * This self-seeding will not occur if <code>setSeed</code> was
     * previously called.</p>
     *
     * @return a new, not already seeded, Pseudo Random Number Generator instance.
     */
    public static SecureRandom createPRNG() {
        try {
            return SecureRandom.getInstance("SHA1PRNG", "SUN");
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
            throw new CryptoConfigurationRuntimeException("Error creating PRNG", e);