/******************************************************************************* * Copyright 2014 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. ******************************************************************************/ /* * Copyright 2003 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. */ package at.gv.egiz.eaaf.core.impl.utils; import java.nio.ByteBuffer; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Random number generator used to generate ID's * @author Paul Ivancsics * @version $Id$ */ public class Random { private static final Logger log = LoggerFactory.getLogger(Random.class); private final static char[] allowedPreFix = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; private static final DateFormat dateFormater = new SimpleDateFormat("yyyyddMM"); /** random number generator used */ private static SecureRandom random; //private static SeedGenerator seedgenerator; static { try { random = SecureRandom.getInstance("SHA256PRNG-FIPS186"); } catch (NoSuchAlgorithmException e) { log.warn("Can NOT initialize SecureRandom with: 'SHA256PRNG-FIPS186'. Use 'StrongSecureRandom' as backup"); try { random = SecureRandom.getInstanceStrong(); } catch (NoSuchAlgorithmException e1) { log.error("Can NOT initialize SecureRandom. StartUp process FAILED!"); throw new RuntimeException("Can NOT initialize SecureRandom. StartUp process FAILED!", e); } } //random = iaik.security.random.SHA256FIPS186Random.getDefault(); } /** * Generate a unique process reference-value [160bit], which always starts with a letter *
* This unique ID consists of single letter, a 64bit date String[yyyyddMM], * and a 88bit random value. * * @return 160bit ID, which is hex encoded */ public static String nextProcessReferenceValue() { //pre-process all three parts of a unique reference value String now = dateFormater.format(new Date()); //8 bytes = 64bit byte[] randValue = nextByteRandom(11); char preFix = allowedPreFix[Math.abs(random.nextInt() % allowedPreFix.length)]; //generate ID String returnValue = preFix + new String(Hex.encodeHex(ArrayUtils.addAll(now.getBytes(), randValue))); // 20 bytes = 160 bits if (returnValue.length() > 40) return returnValue.substring(0, 40); else return returnValue; } /** * Creates a new random number [256bit], and encode it as hex value. * * @return random hex encoded value [256bit] */ public static String nextHexRandom32() { return new String(Hex.encodeHex(nextByteRandom(32))); // 32 bytes = 256 bits } /** * Creates a new random number [128bit], and encode it as hex value. * * @return random hex encoded value [128bit] */ public static String nextHexRandom16() { return new String(Hex.encodeHex(nextByteRandom(16))); // 16 bytes = 128 bits } /** * Creates a new random number [64bit], to be used as an ID. * * @return random long as a String [64bit] */ public static String nextLongRandom() { return "".concat(String.valueOf(Math.abs(generateLongRandom(32)))); // 32 bytes = 256 bits } /** * Creates a new random number, to be used as an ID. * * @return random long as a String [64bit] */ @Deprecated public static String nextRandom() { long l = ByteBuffer.wrap(nextByteRandom(32)).getLong(); // 32 bytes = 256 bits return "" + Math.abs(l); } /** * Creates a new random byte[] * * @param size Size of random number in byte * @return */ public static byte[] nextBytes(int size) { return nextByteRandom(size); } public static void seedRandom() { //TODO: implement reflection on IAIK Seed generator // seedgenerator = iaik.security.random.AutoSeedGenerator.getDefault(); // if (seedgenerator.seedAvailable()) // random.setSeed(seedgenerator.getSeed()); random.setSeed(System.nanoTime()); } private static long generateLongRandom(int size) { return ByteBuffer.wrap(nextByteRandom(size)).getLong(); } /** * Generate a new random number * * @param size Size of random number in byte * @return */ private static synchronized byte[] nextByteRandom(int size) { byte[] b = new byte[size]; random.nextBytes(b); return b; } }