Tag Archives: Security

Cryptographically Secure Random Numbers in Java

The Random Class

Most people wanting to generate random numbers in Java do something similar to the following:
[code lang="java"]public static void main(String[] args) {
Random generator = new Random();
int randomnumber = generator.nextInt(5) + 1;
System.out.println("Dice rolled: " + randomnumber);
}[/code]
This is perfectly fine for a simple dice rolling application where there isn’t going to be much effort put into cracking it. For example in this application the only real reason you would bother cracking it would be to show off a neat party trick to your geeky friends. No doubt though the effort wouldn’t be worth it.

Java states that the Random class and its subclasses must produce predictable results when seeded with the same data. This however is not why this is insecure, and it is useful when testing. The reason that this class is predictable though is the way in which it is seeded. The Random class, in the absence of a seed in its constructor it will seed its random number generator with the current time in milliseconds. This means that if somebody knows the time that the Random object was seeded and has several consecutive bytes of output then they can reasonably predict the next numbers. Once somebody has discovered the seed for the generator all number produced from it can be seen as compromised.

The SecureRandom Class

The SecureRandom class is different, it again uses algorithms that when seeded will produce predictable results, but the algorithm is much more complex. It uses a digest algorithm such as SHA-1 on the seed and a counter to generate random data. SHA-1 is much more costly than the simple algorithm used in the Random class and as such it is much harder to brute force.

Its true strength however lies in the method in which it is seeded. The SecureRandom class is seeded using true random data gathered by the operating system. This is data gathered by the OS from sources of true randomisation, such as mouse movements, network packet arrival times, IO statistics and interrupts. On Linux the data is gathered from /dev/random and on Windows via the CryptGenRandom() call in Windows.

When using SecureRandom though you should be aware of a few things:

  • The more random numbers some can get a hold of the more likely they can figure out the seed. You should either throw away the SecureRandom object every now and then or reseed it. Keeping in mind the next point though.
  • The seeding the generator takes entropy out of the system, if it cannot get any entropy it will block until the system has some. This means if you’re reseeding the generator too often your program will hang along with anything else on the system requiring entropy.
  • Don’t seed the SecureRandom class yourself, unless you are 100% absolutely sure you are seeding it with purely random data, or you are testing and need repeatable results. Whatever you do, don’t let your testing code leak into a production system.

How to decide

Generally when you’re coding you don’t need secure random numbers. For example if you’re writing a number guessing game, or a quiz generating program then high quality random numbers aren’t required. It should be noted though that if money is involved people will often go to greater lengths and a more secure generator will be required, such as in a slot machine.

Again generally if what you are generating is a security token of some sort then you will need a secure generator. For example a session id, a one time password or an encryption key. The exception here is a salt for a password, salts can be generated using predictable entropy sources, even a simple time stamp would work here (especially if your also storing the time stamp to measure password expiry).

Random Thought: For those of you who don’t know Bruce Schneier is the Chuck Norris of cryptography.

Setting Up GPG Keys

Yesterday you may have read my GPG Symmetric Encryption Guide. The last tip on that page was that you should setup GPG keys and publish them on a keyserver. I say this because publishing GPG keys allows you to encrypt things for anyone else who has published their GPG keys without contacting them and exchanging a symmetric key first.

Generating a GPG key

If you haven’t had a GPG or PGP key before, or the one you previously has has expired you will need to generate a new keypair. A keypair consists of a private key, that you keep absolutely secret, and a public key, that you publish to the world.

You should generate a GPG key on your desktop and not on a server. Most likely a server will not have enough entropy in its random number generator and could take a while. All you then have to do is:

gpg --gen-key

You then answer the questions as follows:

  • The type of key that you want is ‘DSA and Elgamal’ this way you can both encrypt messages and sign them.
  • 1024 bits is probably enough, if you are planning a long expiry for your key you may want to choose 2048, and if your extremely paranoid use 4096.
  • I’d suggest a key expiry of two years for a 1024 bit key, but remember you can set an expiry later, and you can also revoke your key at any time if you believe it is compromised.
  • Then you fill in your details in the prompts
  • Never use a key without a passphrase, any compromise of your key will result in all data people have encrypted for you being compromised and people will be able to sign things as coming from you.

After you enter the details you computer will start generating some very large numbers using cryptographically secure random data, and checking if those numbers are prime. Once your computer has two prime numbers it will generate your keys and save them for you.

Add extra uids to the key

A key can contain many uids. For example your key may contain a work uid and a home uid. If you work at many different companies or have a large number of email addresses then you could have many uids. The uids are what people who sign your key are indicating they trust. So I might decide to indicate that I trust your work uid but because I don’t know you personally  To add new uids to the key you type:

gpg --edit-key
Command> adduid

Then just as before you enter all your details. You can list the uids on the key by typing ‘uid’ at that same prompt. When you are done type ‘save’ to save the key.

Entering the web of trust

The first thing you should do is decide what keyserver you would like to publish your keys to. Most keyservers sync with other ones so this is not really that important. I would suggest hkp://keys.gnupg.net but the choice is up to you. When you have decided what keyserver you want to use place an entry in your ~/.gnupg/gpg.conf file like that says ‘keyserver hkp://keys.gnupg.net’ or whatever server you would like to use.

Now you are ready to build the inner circle of your web of trust. To do this you need to get other people to sign your keys, and them to sign yours. The more signatures you build up the easier it is to find a common link between you that is trusted.

To download another persons key you use the receive key argument for GPG. For example to download my key you can use any of the following commands:

gpg --search-keys "Daniel Hall"
gpg --search-keys "smarthall@gmail.com"
gpg --recv-keys "A3A386ED"

The first two may produce multiple matches and may ask you to select which particular key to download. At this point you should contact the user and confirm their ID so you get the right key.

Now that you’ve downloaded your friends keys you need to confirm who they are and then if all check out sign their keys. When you sign somebodies key you need to be extremely careful, signing a key is your declaration to the world that you trust that this key represents this person. If you sign keys without checking you could end up trusting people who aren’t who they say they are and people will begin to stop trusting you. To verify somebody you should meet them personally (or at an absolute minimum talk over the phone) to get their key fingerprint. As you are signing check that this fingerprint matches the key you are about to sign. To sign my key you could use the following command:

gpg --sign-key "A3A386ED"

Then you upload their key to the keyserver again to ensure that your signature on that key is now visible for the world to see. It is polite to ask people before you sign their key as many spam like signatures on a key may look bad in the eyes of others. If you had just signed my key you would upload it with:

gpg --send-key "A3A386ED"

Now all you need to do is get other people to sign your keys. I’d suggest you start with those people whose keys you have just signed as they’ll be the most willing to help you. You aim is to get enough signatures so that everybody who will need to send an encrypted document to you can find someone they trust who trusts you. It is a little more complicated than that but its essentially the idea.

Random Thought: What should the random thought on my next blog post be? Hrmmmm.

GPG Symmetric Encryption

I often come into a situation where I have to exchange some important confidential file with somebody who doesn’t have GPG keys setup. Explaining how to setup keys can be a pain, especially if you believe that the user will lose them or simply forget how to use them. There are all manner of propriety software packages to deal with this but this post is about an easy free way using software that almost anyone has access to. I will be showing you how to do this using GPG on Unix operating systems. For windows you could follow this guide.

Encrypting

To encrypt a file symmetrically using GPG just run:
[code lang="shell"]gpg --symmetric <filename>[/code]
It will prompt you for a password twice and create a <filename>.gpg file in the current directory. If you want to put the encrypted text in an email then add the –armour flag. The –armour flag will cause gpg to instead output a <filename>.asc file which consists of ASCII text.

Decrypting

You decrypt it like any other GPG encrypted file:
[code lang="shell"]gpg -d <filename>.gpg[/code]
This will prompt you for the password and decrypt the file, printing it to standard out.

Tips

  • Don’t send the password and the attachment over the same medium, especially not in the same message. I suggest you send the email with the file and call and tell them the password.
  • GPG uses really strong encryption, much more secure than that used in zipfile encryption. That said if you set the password to ’123′ or ‘password’ no amount of encryption will help you. Your encryption is only as secure as the weakest point.
  • With enough time files like this can be cracked using brute force. You should still do all that you can to prevent the encrypted file falling into the wrong hands.
  • You really should setup GPG keys and publish them to a keyserver. That way you won’t have to worry about secure passphrase distribution.

Random Thought: How did people find the first search engine?

ATM Phishing

You’ve probably heard of ATM fishing by now. If you haven’t you should have. It typically involves placing a card reading device that is designed to blend in perfectly with the ATM. Then a camera or other device is placed that records the PIN of the user as they type it. So effectively while the user is entering their credentials into the ATM they are unwittingly entering them into a scammers database.

In a flash of inspiration last night I think I may have found a solution! My first instinct was to put a poster next to or on the ATM that shows what the ATM looks like. There are a few problems with this though. First, the scammer can simply replace the poster, secondly only the security concious will check it. So this is really a non solution.

So what if you placed pictures of critical parts in the software and display them when the user first puts in their card. Show a shot of the card insertion point, the keyboard and and overall picture. Scammers can’t simply place a poster over the screen as the user needs it to use the ATM. You ask the user to confirm all the pictures and if any don’t match you don’t let them enter their PIN, and possibly eat their card.

I’m not sure how this would work in practice. If the recent response to Vista’s UAC is anything to go by people will probably just click accept on anything. This may get the pictures in their face though. So after seeing this many pictures of ATMs they might more easily notice something amiss. Maybe its a bit ambitious, maybe its not quite scammer proof. What do my readers think?

Random Thought: I’m getting an Android phone because it runs on an ARM CPU. That and my Windows phone is on its last LEGS.

SSH Agent Forwarding

So you use keys to SSH between your hosts, and you either have separate keys for each machine you use, or worse you have the same key on each machine. Lets go over why each of those are bad, and lets see how SSH Agent forwarding will help with those issues and make things easier for you in general.

So the key part of why a SSH agent and SSH agent forwarding forwarding is so useful is due to the way keys can be attacked. If I wanted to get your SSH private key I could find some flaw in the system that would give me that /home/you/.ssh/id_rsa file you have. Of course a malicious user with root access to the system could just go in and grab it. You can prevent this kind of attack by setting a passphrase on the key. Of course the root user could replace SSH with a special version designed to get your passphrase, steal the key out of memory or setup a keylogger. This means effectively that your private key is not safe on any system where a person you don’t trust has root access, or has other users and exploitable vulnerabilities.

Single Private Key on Multiple Machines

In this example you’re trusting the security of every single machine you have your private key on. Should it get compromised then you have to revoke you public key from every host, and regenerate private keys to place on every host. Every time you put your private key on a machine you increase the chances that it could be compromised.

Multiple Private Keys On Multiple Machines

So we’re getting a little closer to a good solution. In this instance we don’t have to generate our key and roll it out to all hosts in event of a compromise. You can also have segregate groups, on set of keys for work, another for home and so on. Your keys can still be compromised easily though, and once compromised they can be used until you revoke them manually.

SSH Agent Forwarding

There is a way to keep your key safe from compromise. Now I’ll have to explain how SSH authenticates you using your key. When your authenticating with SSH keys your key isn’t sent, the server sends you some random data and challenges your client to encrypt it with your private key. It then verifies the encrypted data by decrypting it with the public key and checking if it matches the data originally sent. Now the way most people would SSH from the second host to another third host is to utilise a private key on the second host to connect to the third host. Unfortunately this method means that you have to store a key (that is open for compromise) on the second host. SSH agent forwarding tells the SSH client on the second server to send the challenge data through to the SSH client (or ssh agent) on the first host. The agent encrypts the data and sends it via the SSH session to the third client.

The beauty of this method is that the second host never sees a private key, and the challenge data is useless to try and connect to a different host. Even if the second host is compromised there isn’t a private key there to compromise. It should be noted that if the second host is compromised it can still request the agent identify for a different host, or the session to the third host can be taken over. Both these are temporary though and unless the malicious user installs their key (something easy to notice) they cannot get back in.

Diagram detailing how an SSH connection is authenticated using agent forwarding.

Diagram detailing how an SSH connection is authenticated using agent forwarding.

If you want to know more about how this works, there is a wonderful tech tip at http://unixwiz.net/techtips/ssh-agent-forwarding.html.

But how?

SSH agent forwarding is even easier than copying keys all over the place. The first step is to generate keys for all the machines you log on to directly. You need to be sure these machines are secure and that your keys will stay safe, though this is sometimes not possible. You then add the generated public key to the authorized hosts file of all the machines you will connect to from this one, including ones that take two or more steps to get to. Finally you edit your ~/.ssh/ssh_config file to tell SSH to forward your agent through those hosts. Include the intermediate hosts in this list, but not the endpoints. You could also use SSHmenu to add the arguments automatically to those SSH commands. The following disables forwarding to all hosts, and explicitly enables it to fred, and aaron.missgner.com.

Host fred
  ForwardAgent yes

Host aaron.missgner.com
  ForwardAgent yes

Host *
  ForwardAgent no

Random thought: Linux has Plug ‘n Pray too, you plug the device in and pray the drivers aren’t proprietary.