Commit 736b76f1 authored by Dave Cridland's avatar Dave Cridland

Merge pull request #480 from guusdk/random

Improve quality of random data generation.
parents c58efa58 579a8247
......@@ -28,11 +28,12 @@ import org.dom4j.io.XMPPPacketReader;
import org.jivesoftware.openfire.Connection;
import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.RoutingTable;
import org.jivesoftware.openfire.StreamIDFactory;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.session.LocalSession;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.openfire.spi.BasicStreamIDFactory;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmlpull.v1.XmlPullParser;
......@@ -60,6 +61,12 @@ public abstract class SocketReader implements Runnable {
* The utf-8 charset for decoding and encoding Jabber packet streams.
*/
private static String CHARSET = "UTF-8";
/**
* A factory that generates random stream IDs
*/
private static final StreamIDFactory STREAM_ID_FACTORY = new BasicStreamIDFactory();
/**
* Reuse the same factory for all the connections.
*/
......@@ -394,7 +401,7 @@ public abstract class SocketReader implements Runnable {
// Append stream header
sb.append("<stream:stream ");
sb.append("from=\"").append(serverName).append("\" ");
sb.append("id=\"").append(StringUtils.randomString(5)).append("\" ");
sb.append("id=\"").append( STREAM_ID_FACTORY.createStreamID() ).append( "\" " );
sb.append("xmlns=\"").append(xpp.getNamespace(null)).append("\" ");
sb.append("xmlns:stream=\"").append(xpp.getNamespace("stream")).append("\" ");
sb.append("version=\"1.0\">");
......@@ -423,7 +430,7 @@ public abstract class SocketReader implements Runnable {
// Append stream header
sb.append("<stream:stream ");
sb.append("from=\"").append(serverName).append("\" ");
sb.append("id=\"").append(StringUtils.randomString(5)).append("\" ");
sb.append("id=\"").append( STREAM_ID_FACTORY.createStreamID() ).append( "\" " );
sb.append("xmlns=\"").append(xpp.getNamespace(null)).append("\" ");
sb.append("xmlns:stream=\"").append(xpp.getNamespace("stream")).append("\" ");
sb.append("version=\"1.0\">");
......
......@@ -23,11 +23,13 @@ import org.dom4j.Element;
import org.dom4j.io.XMPPPacketReader;
import org.jivesoftware.openfire.Connection;
import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.StreamIDFactory;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.http.FlashCrossDomainServlet;
import org.jivesoftware.openfire.session.LocalSession;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.openfire.spi.BasicStreamIDFactory;
import org.jivesoftware.openfire.streammanagement.StreamManager;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.LocaleUtils;
......@@ -51,6 +53,11 @@ public abstract class StanzaHandler {
private static final Logger Log = LoggerFactory.getLogger(StanzaHandler.class);
/**
* A factory that generates random stream IDs
*/
private static final StreamIDFactory STREAM_ID_FACTORY = new BasicStreamIDFactory();
/**
* The utf-8 charset for decoding and encoding Jabber packet streams.
*/
......@@ -659,7 +666,7 @@ public abstract class StanzaHandler {
// Append stream header
sb.append("<stream:stream ");
sb.append("from=\"").append(serverName).append("\" ");
sb.append("id=\"").append(StringUtils.randomString(5)).append("\" ");
sb.append("id=\"").append(STREAM_ID_FACTORY.createStreamID()).append("\" ");
sb.append("xmlns=\"").append(xpp.getNamespace(null)).append("\" ");
sb.append("xmlns:stream=\"http://etherx.jabber.org/streams\" ");
sb.append("version=\"1.0\">");
......
......@@ -22,24 +22,31 @@ package org.jivesoftware.openfire.spi;
import org.jivesoftware.openfire.StreamID;
import org.jivesoftware.openfire.StreamIDFactory;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Random;
/**
* A basic stream ID factory that produces id's using java.util.Random
* and a simple hex representation of a random int.
* A basic stream ID factory that produces IDs using a cryptographically strong random number generator.
*
* @author Iain Shigeoka
*/
public class BasicStreamIDFactory implements StreamIDFactory {
/**
* The random number to use, someone with Java can predict stream IDs if they can guess the current seed *
* The maximum amount of characters in a stream ID that's generated by this implementation.
*/
private static final int MAX_STRING_SIZE = 10;
/**
* The random number to use, someone with Java can predict stream IDs if they can guess the current seed
*/
Random random = new Random();
Random random = new SecureRandom();
@Override
public StreamID createStreamID() {
return new BasicStreamID(Integer.toHexString(random.nextInt()));
return new BasicStreamID(new BigInteger( MAX_STRING_SIZE * 5, random ).toString( 36 ));
}
public StreamID createStreamID(String name) {
......
......@@ -15,6 +15,7 @@
package org.jivesoftware.util;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Random;
import org.slf4j.Logger;
......@@ -31,7 +32,7 @@ public class Blowfish implements Encryptor {
private static final Logger Log = LoggerFactory.getLogger(Blowfish.class);
private BlowfishCBC m_bfish;
private static Random m_rndGen = new Random();
private static Random m_rndGen = new SecureRandom();
private static final String DEFAULT_KEY = "Blowfish-CBC";
/**
......@@ -52,9 +53,7 @@ public class Blowfish implements Encryptor {
}
/**
* Encrypts a string (treated in UNICODE) using the
* standard Java random generator, which isn't that
* great for creating IVs
* Encrypts a string (treated in UNICODE).
*
* @param sPlainText string to encrypt
* @return encrypted string in binhex format
......
......@@ -30,6 +30,7 @@ import java.net.IDN;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.BreakIterator;
import java.text.MessageFormat;
import java.util.ArrayList;
......@@ -515,11 +516,9 @@ public final class StringUtils {
}
/**
* Pseudo-random number generator object for use with randomString().
* The Random class is not considered to be cryptographically secure, so
* only use these random Strings for low to medium security applications.
* A cryptographically strong random number generator object for use with randomString().
*/
private static Random randGen = new Random();
private static Random randGen = new SecureRandom();
/**
* Array of numbers and letters of mixed case. Numbers appear in the list
......@@ -532,10 +531,8 @@ public final class StringUtils {
/**
* Returns a random String of numbers and letters (lower and upper case)
* of the specified length. The method uses the Random class that is
* built-in to Java which is suitable for low to medium grade security uses.
* This means that the output is only pseudo random, i.e., each number is
* mathematically generated so is not truly random.
* of the specified length. The method uses a cryptographically strong
* random number generator as provided by {@link SecureRandom}
* <p>
* The specified length must be at least one. If not, the method will return
* null.</p>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment