/*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package io.undertow.server.session;
import java.security.SecureRandom;
A SessionIdGenerator
that uses a secure random to generate a session ID. On some systems this may perform poorly if not enough entropy is available, depending on the algorithm in use. Author: Stuart Douglas
/**
* A {@link SessionIdGenerator} that uses a secure random to generate a
* session ID.
*
* On some systems this may perform poorly if not enough entropy is available,
* depending on the algorithm in use.
*
*
* @author Stuart Douglas
*/
public class SecureRandomSessionIdGenerator implements SessionIdGenerator {
private final SecureRandom random = new SecureRandom();
private volatile int length = 30;
private static final char[] SESSION_ID_ALPHABET;
private static final String ALPHABET_PROPERTY = "io.undertow.server.session.SecureRandomSessionIdGenerator.ALPHABET";
static {
String alphabet = System.getProperty(ALPHABET_PROPERTY, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
if(alphabet.length() != 64) {
throw new RuntimeException("io.undertow.server.session.SecureRandomSessionIdGenerator must be exactly 64 characters long");
}
SESSION_ID_ALPHABET = alphabet.toCharArray();
}
@Override
public String createSessionId() {
final byte[] bytes = new byte[length];
random.nextBytes(bytes);
return new String(encode(bytes));
}
public int getLength() {
return length;
}
public void setLength(final int length) {
this.length = length;
}
Encode the bytes into a String with a slightly modified Base64-algorithm
This code was written by Kevin Kelley
and adapted by Thomas Peuss
Params: - data – The bytes you want to encode
Returns: the encoded String
/**
* Encode the bytes into a String with a slightly modified Base64-algorithm
* This code was written by Kevin Kelley <kelley@ruralnet.net>
* and adapted by Thomas Peuss <jboss@peuss.de>
*
* @param data The bytes you want to encode
* @return the encoded String
*/
private char[] encode(byte[] data) {
char[] out = new char[((data.length + 2) / 3) * 4];
char[] alphabet = SESSION_ID_ALPHABET;
//
// 3 bytes encode to 4 chars. Output is always an even
// multiple of 4 characters.
//
for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
boolean quad = false;
boolean trip = false;
int val = (0xFF & (int) data[i]);
val <<= 8;
if ((i + 1) < data.length) {
val |= (0xFF & (int) data[i + 1]);
trip = true;
}
val <<= 8;
if ((i + 2) < data.length) {
val |= (0xFF & (int) data[i + 2]);
quad = true;
}
out[index + 3] = alphabet[(quad ? (val & 0x3F) : 63)];
val >>= 6;
out[index + 2] = alphabet[(trip ? (val & 0x3F) : 63)];
val >>= 6;
out[index + 1] = alphabet[val & 0x3F];
val >>= 6;
out[index] = alphabet[val & 0x3F];
}
return out;
}
}