2

Im currently looking to write a user input orientated method for generating a secure AES key. the application is to be a console application which takes user input via the replication of a randomly generated text string where the interval time between key presses is taken into account for generating the random AES key. Is there any way for me to go about doing this?

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
tinylanda
  • 21
  • 3
  • Do you really need this kind of source of entropy? Can't you just ask the user for the necessary seeds or just get them from the system's random number generator? – hugomg Jul 29 '11 at 19:47

4 Answers4

1

There seems to be no portable way. You need to read a single character, which isn't enabled by default, not even using the Console class. Usually, Java just reads in the entire line. Here's the question of how to get around that. Summary: knock your console into raw mode.

Assuming you're on a unix system, this works (tested on OSX):

import java.io.Console;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;


public class Main {

    public static void main(String[] args) throws IOException, InterruptedException {
        String[] cmd = {"/bin/sh", "-c", "stty raw </dev/tty"};
        Runtime.getRuntime().exec(cmd).waitFor();
        Console console = System.console();
        Reader reader = console.reader();
        ArrayList<Long> timeStamps = new ArrayList<Long>();
        StringBuilder password = new StringBuilder();
        timeStamps.add(System.currentTimeMillis());
        System.out.println("Enter your 8 character password");
        for(int i = 0;i<8;i++) {
            password.append(reader.read());
            timeStamps.add(System.currentTimeMillis());
        }
        System.out.println("Timestamps: ");
        System.out.println(timeStamps);
        cmd = new String[] {"/bin/sh", "-c", "stty sane </dev/tty"};
        Runtime.getRuntime().exec(cmd).waitFor();           
    }
}
Community
  • 1
  • 1
nes1983
  • 15,209
  • 4
  • 44
  • 64
1

Not really an answer to your question, but is there any reason why KeyGenerator won't fit your purpose?

KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256, SecureRandom.getInstance("SHA1PRNG"));
Qwerky
  • 18,217
  • 6
  • 44
  • 80
  • That's just it, the assignment is a cryptography assignment, the code to generate the AES key has to be my own.. – tinylanda Jul 29 '11 at 16:03
  • @tinylanda: Only the code for generating the key, or also generating the random data for it? (E.g. can you use SecureRandom, even if not the KeyGenerator)? – Paŭlo Ebermann Jul 29 '11 at 16:08
  • I was going to implement blum blum shub and start shaving bits but im looking for a none algorithmic random to generate the key, everything behind the AES needs to be my own.. That said im looking at generating a plaintext from different variables, then using the MessageDigest() whith SHA256 to generate the 256 AES.. – tinylanda Jul 29 '11 at 16:15
  • @tinylanda Using a SHA256 hash of a password is a fairly common technique for generating AES keys, but remember your key is only as strong as your password. – Qwerky Aug 01 '11 at 08:31
0

Very stupid answer maybe, but can the "any key" be replaced by the enter key? In that case, you can use the precise timing and jitter from reading lines instead of separate characters. You may use System.nanoTime() to - possibly - add some entropy. Note that although normally such a scheme would give you some entropy, it's sufficiently JVM, OS and machine dependent to not use it in the field.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
0

JLine may help. The library has some native code but works on different platforms, and can read single characters from the console.

prunge
  • 22,460
  • 3
  • 73
  • 80