Reimplementing mkpasswd - java

On Linux I am used to using mkpasswd to generate random passwords to use, on OS X however I don't have this command. Instead of sshing in to my vps every time, I wanted to re implement it using Java. What I have done is pick at random 4 lower case letters, 2 upper case letters, 2 symbols (/ . , etc) and 2 numbers. Then I create a vector and shuffle that too.
Do you think this is good enough randomization?

If you use java.security.SecureRandom instead of java.util.Random then it's probably secure. SecureRandom provides a "cryptographically strong pseudo-random number generator (PRNG)". I.e. it ensures that the seed cannot easily be guessed and that the numbers generated have high entropy.

yes, it is. If you are using java.util.Random:
An instance of this class is used to generate a stream of pseudorandom numbers. The class uses a 48-bit seed, which is modified using a linear congruential formula. (See Donald Knuth, The Art of Computer Programming, Volume 2, Section 3.2.1.)
The algorithms implemented by class Random use a protected utility method that on each invocation can supply up to 32 pseudorandomly generated bits.
EDIT
in response to a comment:
/**
* Creates a new random number generator. This constructor sets
* the seed of the random number generator to a value very likely
* to be distinct from any other invocation of this constructor.
*/
public Random() {
this(++seedUniquifier + System.nanoTime());
}
private static volatile long seedUniquifier = 8682522807148012L;

There is a similar pwgen command available in the Mac Ports.

Depends on where your entropy comes from. Using rand() or similar functions that your particular language comes with may not be secure.
On OSX you can use /dev/random I think.

It might be OK, but you should allow some randomization in password lengths perhaps.
If your program became popular it would become a weakness that the password length was public knowledge. Also randomize the exact ratio of lowercase:uppercase:symbols:numbers a little.

Why not just compile mkpasswd on your OS X host?

Related

Why there is no nextDouble(), nextFloat() and nextLong() which accept a bound in java.util.Random

I was reading java.util.Random class and noticed that there is no nextDouble(), nextFloat() and nextLong() which can accept a bound.
There are many way to get it done like this.
But my question is why java did not provide us with these required method like nextInt(int n) which accept the bound.
Is there any specific reason they did not provide these methods?
A good API always tries to provide the essential elements that a user needs to do his job.
Having nextInt(int n) is just one possible implementation. What if you need other distributions?!
In other words: the Random API could try to anticipate all potential usage patterns, but that would very much bloat the whole API. Instead, the designers choice a very small interface - but you got all the elements required to build your own things on top of that.
Thing is: in the end, this is a design style decision by the people who created the Random class. And as so often, problems could be solved in many different ways. Thus you shouldn't draw deep conclusions on the solution that was picked here.
Looking at the code from Random.java (in jdk 8) there are two statements that stand out.
* The algorithm is slightly tricky. It rejects values that would result
* in an uneven distribution (due to the fact that 2^31 is not divisible
* by n). The probability of a value being rejected depends on n.
and
* Linear congruential pseudo-random number generators such as the one
* implemented by this class are known to have short periods in the
* sequence of values of their low-order bits.
Without being an expert in random number generation (they refer to it as pseudo random number generation), it seems evident that the algorithm is trying to to a better job of returning "random" numbers than if you simply did next() % bound, in terms of randomness (and possibly also efficiency).
There is also the convenience factor but that doesn't seem to be the primary reason, given the comments in the code.

Please explain me the role of seed in class Random in java.util

Whenever we create an object of Random class in java. We either of the constructor
Random()
Random(long seed)
What is the purpose of seed here in the 2nd constructor and how can I use it to my benefit i.e. manipulate its use?
The answer above sums it up clearly. As per java api docs from oracle, the first constructor
Random()
"Creates a new random number generator. This constructor sets the seed of the random number generator to a value very likely to be distinct from any other invocation of this constructor. "
The seed is probably a derivative of the current time, or the current time itself. That should be enough to be "very likely to be distinct from any other invocation". Which, in essence, is most likely what you need, most of the time.
So why have another constructor that takes a seed?
Simply put, if you want to generate the same set of random numbers over and over, you use the same seed on your Random constructor. This is useful when doing experiments on different control sets, and you don't want to bother creating your own table of random inputs, but still want the same set of random input on a different experiment/control set.
There's no such thing as truly random numbers in computing. The available methods for getting a random number across all programming languages is nothing but an algorithm to simulate random numbers.
In some languages (C++, I know for sure), an unseeded random number generator will return the same series of numbers on every fresh execution of the program.
What is common is to seed the random number generator with the current time (which will be random enough for most purposes) so that the algorithm starts with a random number each time.
Pseudo-random number generators maintain some set of state information, which is advanced through some recurrence relation to determine the next value of the state. The output of a PRNG is some function of the state. Java's Random class uses a Linear Congruential Generator. LCG's work using the recurrence relationship Ui+1 = (A Ui + C) % M for some constant integer values A, C, and M. Java's current implementation uses a 48-bit state but uses 32 bits or less of it on each iteration of the recurrence.
Based on this, you can see that if you start with the same state you will get the exact same sequence of values out of your PRNG. This can be useful if you want to be able to reproduce exactly the same sequence of "randomness", for instance for debugging or for comparing two experiments head-to-head.
If you invoke the constructor without an argument, it picks a starting value for the state with a promise that different invocations are very likely to be distinct from each other. If you supply a seed to the constructor, that seed's value is used to set the initial state.

C's stdlib rand() function in Java

I've generated a series of random numbers from a known seed in C using srand() and rand() from stdlib. I now need to generate the same series of numbers using the same seed from C in Java.
Java's Random class documentation states it uses a "linear congruential formula". The documentation I've found on rand() says it uses a "linear congruential" generator, although I'm not sure if this is for one specific implementation.
Does anyone know if both generators will produce the same numbers if given the same seed or if a port of srand() and rand() exists for Java?
The C standard does not dictate the implementations of srand() and rand(). As such, different environments (OS, C libraries, architecture, etc.) will more than likely produce sequences of numbers that are different for the same seed value.
Also, the implementation Java's Random class is not bound to any particular algorithm. Here again, different JVMs may very well produce different sequences for the same seed value. In addition, the implementation will more than likely not be tied to the standard C functions. Which means, the Java produced sequence will be different than a C sequence using the same seed.
If you truly need to generate random sequence in Java to match exactly that of the standard C functions, the best you could hope to do is replicate the sequence for a particular environment. This would require creating a JNI library to proxy calls to srand() and rand() or creating some other external process that makes the calls and is invoked from Java. Either way, that's a lot of complexity and more program maintenance.
If in fact all you need are random sequences that appear to be uniformly distributed, regardless of the exact values, then use Random as is. It is more than sufficient for most RNG needs.
As said in other answer, the C standard doesn't even specify that rand() will return the same sequence across different C platforms (libraries), and likewise nothing in Java guarantees that it matches any given C (or other Java) implementation. You could use JNI to call the specific C implementation on that platform, but this would only guarantee the same sequence to be produced when both the C and Java programs are run on the same platform using the same C library.
If you wish to ensure the same sequence in all situations, you need to implement the same random number generator in both languages. A simple example can be found in POSIX.1-2001, and is quoted on many man 3 rand pages:
static unsigned long next = 1;
/* RAND_MAX assumed to be 32767 */
int myrand(void) {
next = next * 1103515245 + 12345;
return((unsigned)(next/65536) % 32768);
}
void mysrand(unsigned seed) {
next = seed;
}
It is trivially portable to Java. The quality of randomness produced this generator is not very high, but it's not really guaranteed to be any better with rand() either, so you would need to implement something fancier if better randomness is required.
In both C and Java, the same seed will generate the same random values. While the underlying mechanism might be different, this property is maintained in every programming language I know about.
C and Java will probably not generate the same set of random numbers given a seed. The only property that is maintained is that given a seed, a programming language will generate the same random numbers.

Will this algorithm generate a cryptographically-secure bitstream?

I'm in the rough stages of creating a Spades game and I'm having a hard time thinking up a cryptographically-secure way to shuffle the cards. So far, I have this:
Grab 32-bit system time before calling Random
Grab 32 bits from Random
Grab 32-bit system time after calling Random
Multiply the system times together bitwise and xor the two halves together
xor the 32 bits from Random with the value from the first xor, and call this the seed
Create a new Random using the seed
And basically from here I both save the 32-bit result from each Random instance and use it to seed the next instance until I get my desired amount of entropy. From here I create an alternating-step generator to produce the final 48-bit seed value I use for my final Random instance to shuffle the cards.
My question pertains to the portion before the alternating-step generator, but if not, since I'll be using a CSPRNG anyway would this algorithm be good enough?
Alternatively, would the final Random instance be absolutely necessary? Could I get away with grabbing six bits at a time off the ASG and taking the value mod 52?
No, it may be secure enough for your purposes, but it is certainly not cryptographically secure. On a fast system you may have two identical system times. On top of that, the multiplication will only remove entropy.
If you wan't, you can download the FIPS tests for RNG's and input a load of data using your RNG, then test it. Note that even I have trouble actually reading the documentation on the RNG tests, so be prepared to do some math.
All this while the Java platform already contains a secure PRNG (which is based on SHA1 and uses the RNG of the operating system as seed). The operating system almost certainly uses some time based information as seed, no need to input it yourself (of course you may always seed the system time if you really want to).
Sometimes the easy answer is the best one:
List<Card> deck; // Get this from whereever.
SecureRandom rnd = new SecureRandom();
java.util.Collections.shuffle(deck, rnd);
// deck is now securely shuffled!
You need a good shuffling algorithm and a way of gathering enough entropy to feed it so that it can theoretically cover all possible permutations for a deck of cards. See this earlier question: Commercial-grade randomization for Poker game

Java Random seed

I need to test out a Java program 20 times and need to set the random seed so that the tests can be repeated. If I were to set the initial seed as 0 and then increment by 1 at each run (i.e. 1,2,3 etc), would this method still ensure complete randomness, even though the seeds are not far apart?
Thank you
Any seed will provide the same level of randomness as any other seed for a standard PRNG like the one included with Java. So it's fine to use an incrementing seed for tests.
You might want to consider using a better random number generator though. The one included with Java yields noticeable repeating patterns if you render the values as an image (I can't find a reference offhand, but I recall it being apparent). I'd recommend the Mersenne Twister (there are Java versions) as an alternative that's fast and has a very long period so you won't easily see patterns.
If you use a seed of 0 the sequence of random numbers will be repeatable from that point. You would only need to use a different random seed if you wanted a different sequence. i.e. you should be able to set the seed once per test.
Why not just use the current time as the seed? ie, System.currentTimeMillis() ?
Do you need a number or a string? I use UUID.randomUUID().toString() to get a UUID for my tests when I need strings, but if you need a number then you can use System.nanoTime().

Categories

Resources