Updated: I’ve rejigged all of this into a public, automatic key generator, that you can see here: http://www.danielbray.com/php/keygen/.


I got a broadband a while back, and it came with a wireless router, which was just enough to tip my natural anxiety over into full-blown paranoia.

So, I spent a bit of time investigating how safe I could make my router and I came up with the following. I won’t go into too much detail, because people who know more about this have already done that here, and here.

First you need to hide your SSID and limit your network access to specific MAC addresses. This won’t do a huge amount to protect your network, but it will, at least, prevent your neighbours from using up your bandwidth since it would only take a wireless-enabled laptop to be switched on near your router for your network to be compromised. It’s not a real safety measure since the wi-fi protocol requires that the SSID be broadcast occasionally, and it’s actually pretty easy to sniff this out and instruct your network card to identify itself with a different MAC address.

So the only real way to secure your network is to encrypt the traffic so that nobody can read what your up to, won’t be able to read your personal data and won’t be able to join your network.

If you’re doing this at home (as I am) then you’re pretty much going to be restricted to using either WEP or WPA-PSK. Both are crackable, but WEP is fundamentally flawed, whereas WPA-PSK is only really broken if your pre-shared key is too small. You’re going to hear a lot of noise that WPA-PSK is “easy” to crack, but if you do it right you’re pretty safe.

If your pre-shared key is “presharedkey” then you deserve whatever you get.

So, what’s a good pre-shared key? It’s simple enough: it needs to be as long as possible, from as large an alphabet as possible, and to be as random as possible.

What you don’t want to do is to use anything approaching a natural language, there are too many tools out there like john the ripper that are just far too good at breaking keys like this. Luckily, a network pre-shared key doesn’t need to be able to be remembered: you’re not going to be typing this in every time you “log in,” you’re only going to have to type this in once when you set up your network connection.

So, what to do? First you need a whole bunch of random numbers. That is, real random numbers, and not numbers generated by software (they’re not really random). I get my random numbers from http://www.random.org, who get their random numbers by pointing an antenna at the sky and reading the satic, which is about as random as you can get.

The next thing to do is to turn these numbers into a string that you can paste into your router/clients. I did it with a bit of java. It’s in java 1.5, but if you use earlier versions there’s only the tinest bit of auto-boxing, so it’s trivial to retrofit it.

The first thing I needed to do was to get random.org to give me the numbers I needed in as simple a format as they could. Luckily, it turned out to be trivial to get it to return a plain list of numbers, one per line. All I needed to do was to open the following URL and read what it gave me.

http://www.random.org/cgi-bin/randnum?num=100&min=1&max=10&col=1

The above example will return 100 numbers (num=100) between 1 (min=1) and 10 (max=10). It was a simple task to get this to return the numbers I wanted. All I had to do then was to figure out what were the numbers I wanted.

The best advice I can find out there is that the pre-shared key should be at least 20 characters, but if you make it longer you should: I made mine as big as I could, at 63 characters. The next thing I needed to worry about was how to turn these numbers into a string.

This is very easy, it’s just case of turning these numbers into ASCII characters. I wanted to make my pre-shared key as complex, and as hard to crack as possible, which meant I needed to make the alphabet as larges as possible. This turned out to be all the characters between 33 (”!“) and 126 (”-“), but your own router might not allow this range.

So, first you need to create your URL to poke at random.org.

// how long should the password be
int passwordLength = 63;

// What's the minimum ASCII character allowed in the password
int minCharacter = 33;

// What's the maximum ASCII character allowed in the password
int maxCharacter = 126;

// this URL will return a plaintext page of numbers, between
// min and max, one per line
String unformattedUrlString =
"http://www.random.org/cgi-bin/randnum?num={0}&min={1}&max={2}&col=1";

String formattedUrlString = MessageFormat.format(
unformattedUrlString,
new Object[]{
passwordLength,
minCharacter,
maxCharacter
}
);

URL url = new URL(formattedUrlString);

Now you want to open a connection to this URL, read the data, and turn it int a list of numbers.

private List getNumbers(URL url) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));

List keyElements = new ArrayList();
while (true) {
final String read = in.readLine();
if (read == null) {
break;
} else {
int value = (int)Integer.parseInt(read);
keyElements.add(value);
}
}

return keyElements;
}

Now you want to turn this list of numbers into a string.

private String getPasswordFromNumbers(List elements) {

StringBuffer buffer = new StringBuffer();
for (Integer element : elements) {
char character = (char)element.intValue();
buffer.append(character);
}

String password = buffer.toString();
return password;
}

This pre-shared key is strong. At 9463 combinations (that’s about one and a half times as many protons and neutrons there are in the whole universe) it’s stronger than anything you’re ever liable to actually need, so until someone finds the same kind of deep flaw in WPA-PSK that they found in WEP your network encryption should be good enough to be getting on with.

If you don’t want to go to the effort of writing this up yourself then you can grab the wpa.jar from here. The jar contains the source and the javadocs too. If you want to run it, then just go:

java -jar wpa.jar

The output is like this:

cnMpO'5s:_=?[z42L25C`Sro"~ke27

Enjoy your safe networking! Let me know how it works out.