I’m writing a Java program that needs to extract a 32 character key from the system’s /dev/urandom interface. For this, I’m using the following procedure:
public String generateKey() {
try {
Runtime run = Runtime.getRuntime();
Process pr = run.exec("tr -cd '[:alnum:]' < /dev/urandom | fold -w30 | head -n1;echo;");
pr.waitFor();
BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = buf.readLine())!= null ) {
sb.append(line);
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
return "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
}
}
(If it can’t do it then it will return a bunch of null characters)
For some reason it’s returning nothing (or throwing an exception and not printing the stack trace). I know this because I print it out to the console (nothing) and when I give it to my RC4 engine it throws a divide by zero error. Why is the command not working and how could I make it work?
Thank you for the help.
Edit: Not two minutes after I posted this I have deduced it’s not returning the null characters because I set it to return the word “lemons” and it did the same thing so it’s not throwing an exception.
Edit 2: As per a suggestion in the comments I tried to read right from the file with the same results but I think I may be doing this wrong…
File file = new File("/dev/urandom");
FileReader freader = null;
StringBuffer sb = new StringBuffer();
int x = 0;
try {
freader = new FileReader(file);
BufferedReader reader = new BufferedReader(freader);
for (int i=0;(i<32||(x=reader.read())==-1);i++) {
sb.append((char) x);
}
return sb.toString();
} catch(Exception e) {
e.printStackTrace();
return "a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
}
Edit 3: This may be helpful to those helping:
Using the above code and piping the output to od I found it’s just reading 0s. (Again, it’s not throwing an exception otherwise it wouldn’t be all zeros:)
# ./run.sh | od
0000000 000000 000000 000000 000000 000000 000000 000000 000000
*
As already indicated by user
Miserable Variable, try to run your commands inside an actual Unix shell; and make sure the shell gets invoked as an interactive shell (sh -i -c 'cmd1 | cmd2').Otherwise the UNIX piping mechanism seems to get blocked because
trkeeps reading from/dev/urandombut for some reason refuses to write to itsstdout.Executed in
Terminal.appthough the following command runs without any hiccups:sh -c 'LC_ALL=C tr -cd [:alnum:] < /dev/urandom | fold -w30 | head -n1; echo;'Another approach would be to explicitly limit the number of bytes read from
/dev/urandom(see code below).