Java tutorial
/* Copyright 2006, Queensland University of Technology * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * Author: Bradley Beddoes * Creation Date: 03/10/2006 * * Purpose: Generates random identifiers compliant to the IdentiferGenerator interface specification */ package com.qut.middleware.saml2.identifier.impl; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.concurrent.locks.ReentrantLock; import org.apache.commons.codec.binary.Hex; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.qut.middleware.saml2.identifier.IdentifierCache; import com.qut.middleware.saml2.identifier.IdentifierGenerator; import com.qut.middleware.saml2.identifier.exception.IdentifierCollisionException; import com.qut.middleware.saml2.identifier.exception.IdentifierGeneratorException; /** Generates random identifiers compliant to the IdentiferGenerator interface specification. */ public class IdentifierGeneratorImpl implements IdentifierGenerator { private final String XS_ID_DELIM = "_"; //$NON-NLS-1$ private final String ID_DELIM = "-"; //$NON-NLS-1$ private final String RNG = "SHA1PRNG"; //$NON-NLS-1$ /* Local logging instance */ private Logger logger = LoggerFactory.getLogger(IdentifierGeneratorImpl.class.getName()); private IdentifierCache cache; private ReentrantLock lock; private SecureRandom random; public IdentifierGeneratorImpl(IdentifierCache cache) { if (cache == null) { throw new IllegalArgumentException("identifier cache cannot be null."); //$NON-NLS-1$ } this.cache = cache; this.lock = new ReentrantLock(); try { /* Attempt to get the specified RNG instance */ this.random = SecureRandom.getInstance(this.RNG); } catch (NoSuchAlgorithmException nsae) { this.logger.error(Messages.getString("IdentifierGeneratorImpl.13")); //$NON-NLS-1$ this.logger.debug(nsae.getLocalizedMessage(), nsae); this.random = new SecureRandom(); } this.random.setSeed(System.currentTimeMillis()); } /* (non-Javadoc) * @see com.qut.middleware.saml2.identifier.IdentifierGenerator#generateSAMLAuthnID() */ public String generateSAMLAuthnID() { String id = this.XS_ID_DELIM; id = id + generate(20); id = id + this.ID_DELIM + generate(16); this.logger.debug(Messages.getString("IdentifierGeneratorImpl.0") + id); //$NON-NLS-1$ try { this.cache.registerIdentifier(id); } catch (IdentifierCollisionException e) { this.logger.error(Messages.getString("IdentifierGeneratorImpl.1")); //$NON-NLS-1$ this.logger.debug(e.getLocalizedMessage(), e); throw new IdentifierGeneratorException(Messages.getString("IdentifierGeneratorImpl.2")); //$NON-NLS-1$ } return id; } /* (non-Javadoc) * @see com.qut.middleware.saml2.identifier.IdentifierGenerator#generateSAMLID() */ public String generateSAMLID() { String id = this.XS_ID_DELIM; id = id + generate(20); id = id + this.ID_DELIM + generate(16); this.logger.debug(Messages.getString("IdentifierGeneratorImpl.3") + id); //$NON-NLS-1$ try { this.cache.registerIdentifier(id); } catch (IdentifierCollisionException e) { this.logger.error(Messages.getString("IdentifierGeneratorImpl.4")); //$NON-NLS-1$ this.logger.debug(e.getLocalizedMessage(), e); throw new IdentifierGeneratorException(Messages.getString("IdentifierGeneratorImpl.5")); //$NON-NLS-1$ } return id; } /* (non-Javadoc) * @see com.qut.middleware.saml2.identifier.IdentifierGenerator#generateSAMLSessionID() */ public String generateSAMLSessionID() { String id = generate(10); this.logger.debug(Messages.getString("IdentifierGeneratorImpl.6") + id); //$NON-NLS-1$ try { this.cache.registerIdentifier(id); } catch (IdentifierCollisionException e) { this.logger.error(Messages.getString("IdentifierGeneratorImpl.7")); //$NON-NLS-1$ this.logger.debug(e.getLocalizedMessage(), e); throw new IdentifierGeneratorException(Messages.getString("IdentifierGeneratorImpl.8")); //$NON-NLS-1$ } return id; } /* (non-Javadoc) * @see com.qut.middleware.saml2.identifier.IdentifierGenerator#generateXMLKeyName() */ public String generateXMLKeyName() { String id = generate(8); this.logger.debug(Messages.getString("IdentifierGeneratorImpl.9") + id); //$NON-NLS-1$ return id; } /* (non-Javadoc) * @see com.qut.middleware.saml2.identifier.IdentifierGenerator#generateSessionID() */ public String generateSessionID() { String id = generate(20); id = id + this.ID_DELIM + generate(16); id = id + this.ID_DELIM + System.currentTimeMillis(); this.logger.debug(Messages.getString("IdentifierGeneratorImpl.10") + id); //$NON-NLS-1$ try { this.cache.registerIdentifier(id); } catch (IdentifierCollisionException e) { this.logger.error(Messages.getString("IdentifierGeneratorImpl.11")); //$NON-NLS-1$ this.logger.debug(e.getLocalizedMessage(), e); throw new IdentifierGeneratorException(Messages.getString("IdentifierGeneratorImpl.12")); //$NON-NLS-1$ } return id; } /** * Generates the specified number of random bytes using SecureRandom * * @param length * The number of random bytes to generate * @return The generated random string */ private String generate(int length) { String id; byte[] buf; buf = new byte[length]; this.lock.lock(); try { /* Seed the specified RNG instance and get bytes */ this.random.setSeed(Thread.currentThread().getName().getBytes()); this.random.setSeed(System.currentTimeMillis()); this.random.nextBytes(buf); } finally { this.lock.unlock(); } id = new String(Hex.encodeHex(buf)); return id; } }