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
*
throwsclause. If this is unadvisable for other means (i.e. larger context), simply wrap it as an Unchecked:try { .. } catch (Exception ex) { throw new RuntimeException(ex); }. The difference between this and plain logging is this still propagates an exception up - yay! Only suppress an exception if there is something useful to do with it (which might be "suppressing it" in cases, but not here/in a test-case).