Broken RSA Keys (part 3: openssl)

Openssl uses the RANDFILE environment variable or configuration setting in its config file to specify the location of a random seed. During key generation, this seed is combined with a few bytes from /dev/urandom, to be used as a new seed for the openssl internal pseudorandom number generator.

In most systems, you can find your own personal openssl seed in ~/.rnd, and for the purposes of this blog post, I am going to use ~/.rnd and RANDFILE interchangeably. But of course, you need to use whatever is the correct RANDFILE in your configuration. Upon first run, openssl should generate ~/.rnd for you. If you generate some key with openssl and ~/.rnd still doesn’t exist, you better dig into your environment variables and openssl config file to find RANDFILE. You’re going to need it momentarily.

Every time openssl reads ~/.rnd, it overwrites the file with a new random seed for next time. So to ensure strong entropy using openssl, all you need to do is ensure strong entropy entered into this file once. After that, you may safely assume all your openssl operations on that machine include high entropy.

This file is 1k long (8192 bits) but your openssl private key has a cryptographic strength around 128 or 256 bits (a 3072 bit RSA or DH private key has a cryptographic strength of 128 bits). Also, when openssl reads your RANDFILE, it will include additional bytes from urandom, which can only strengthen your key further. So we don’t need anywhere near 8192 bits of entropy in your RANDFILE. 32 bytes = 256 bits

There are lots of easy ways to get this wrong. You could be reading the wrong openssl.cnf file. Maybe you had a type-o when you set RANDFILE. Maybe the openssl you’re using ignores your RANDFILE environment variable. To eliminate all of these possible sources of error, do this:

  • Run your openssl command.
  • Now check your ~/.rnd file (or whatever RANDFILE) to ensure it exists.
  • Get the md5sum.
  • Run your openssl command again.
  • Get the new md5sum, and ensure it’s different from before. This will ensure you’re definitely looking at the right RANDFILE, which is definitely being used by your openssl command.

Now, overwrite that file with a new random seed:
dd if=/dev/random bs=1 count=32 of=~/.rnd

After generating a new random seed file, run your openssl command for real, trusting that you have strong entropy from now on.

Please see also:

Broken RSA Keys (part1: the problem)
and
Broken RSA Keys (part 2: fixing ssh keys)

Broken RSA Keys (part 2: fixing ssh keys)

As mentioned in a previous post, there are problems with people generating keys with insufficient entropy. This is particularly a problem for ssh, which generates the host ssh keys upon first boot, when there was probably insufficient entropy available.

If you’re generating ssh keys (ssh-keygen) you can solve the problem by using SSH_USE_STRONG_RNG as shown below. Note, in this command, it’s bytes. So 32 equals 256 bits.

To generate good SSH Keys (assuming redhat derivative linux):

sudo mkdir /etc/ssh/oldkeys
sudo mv /etc/ssh/*_key* /etc/ssh/oldkeys

export SSH_USE_STRONG_RNG=32
sudo ssh-keygen -q -C "" -N "" -t dsa -f /etc/ssh/ssh_host_dsa_key
sudo ssh-keygen -q -C "" -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key
sudo ssh-keygen -q -C "" -N "" -t rsa1 -f /etc/ssh/ssh_host_key

sudo chmod 600 /etc/ssh/*_key
sudo chmod 644 /etc/ssh/*_key.pub
sudo chown root:root /etc/ssh/*key*

sudo service sshd restart

Please also see:
Broken RSA Keys (part1: the problem)
and
Broken RSA Keys (part 3: openssl)

Broken RSA Keys (part1: the problem)

Lots of stories circulating the news right now (such as this one) about RSA keys providing no security. The problem is not RSA. The problem is bad random seeds when you generated your keys. The solution: Generate new keys using good randomness.

The word for “randomness” is “entropy.” Entropy is the measure of unpredictability. A single fair coin toss represents a single bit of entropy.

For the moment, I’ll write about linux specifically. Much of this information comes from man (4) random.

/dev/random is gathered from hardware entropy sources, such as TPM and keyboard & mouse movements, and unpredictable disk seek times and supposedly unpredictable characteristics of the ethernet and hardware interrupts, etc. Since there is a limited amount of system entropy available, if you try to read /dev/random, your read will block (stall) until more bytes become available.

/dev/urandom is a pseudorandom number generator, based on hash algorithms or ciphers or similar. It is actually deterministic given the initial seed. This is a non-blocking device, so you can read infinite bytes from it as fast as the CPU can generate them. If you read enough data from /dev/urandom, it may exhaust any available entropy, and it will be reused. In other words, a pattern will emerge.

As entropy becomes available in /dev/random, it is fed into /dev/urandom. This helps to continually re-seed urandom and helps urandom to be more actually unpredictable. Basically, urandom is an amplifier of the true entropy.

Unfortunately, when a system is freshly installed, upon first boot, there hasn’t been much entropy gathered. It’s fairly deterministic. During first boot, even if you use urandom, it is only amplifying a very small amount of actual entropy. This is when your ssh keys get generated.

Clearly, you should generate new server ssh keys (and any other keys) sometime after you can assure sufficient entropy. The question is, how do you know you have sufficient entropy in your key generation process?

I’m going to answer this question in two parts, separately. Once for ssh, and once for openssl. Please see:
Broken RSA Keys (part 2: fixing ssh keys)
and
Broken RSA Keys (part 3: openssl)

Competitive Advantage

There is a level of support (IT and otherwise) that is necessary just to keep the doors open for business. Many businesses cut their support down to this level, thinking of us as “overhead.” But beyond that point – IT is a force multiplier, we provide competitive advantage (neutralizing competitors’ advantage, or gaining our own competitive advantage). Both in terms of our organization’s ability to produce more and meet more targets, and in terms of our ability to attract & retain talented workforce.

When you think about it, most of the “coolness” factors of an organization are support related, IT and otherwise. Coolness factors represent a real, but often intangible or unmeasurable, advantage to attracting & retaining talent. It’s company image, it’s marketing for your brand.

selinux notes

These are my notes, after learning from Fedora Selinux FAQ

  • Become root. Although you could do this with sudo, it’s more of a pain.
    Also, you may be glad, some day, that you left these files laying around, and the best place for that is in root’s home directory (or a subdirectory.)

  • You must ensure the auditd service is installed and started.
    yum -y install auditd policycoreutils-python
    service auditd start

  • First, make sure there’s nothing in your audit log.
    audit2allow -m local -l -i /var/log/audit/audit.log
    If there is anything in there, clear it out with
    semodule --reload

  • Now, temporarily disable selinux
    setenforce 0

  • Do whatever would normally get blocked.

  • And re-enable selinux
    setenforce 1

  • Make up a new module name, such as “httpdwritehomes” and prepare that module from the list of stuff that was captured in the audit log:
    export newmod=httpdwritehomes
    audit2allow -m $newmod -l -i /var/log/audit/audit.log > $newmod.te
    Be sure to edit that file, read it over, and remove anything that doesn’t belong

  • Note: If nothing appears in the logs, you might have to disable “don’taudit” See http://danwalsh.livejournal.com/11673.html
    semodule -DB
    and later
    semodule -B

  • Now compile and install the new module
    checkmodule -M -m -o $newmod.mod $newmod.te
    semodule_package -o $newmod.pp -m $newmod.mod
    semodule -i $newmod.pp