0.17.0 Fix for Non Random Passphrases - ligos/readablepassphrasegenerator GitHub Wiki

Fix for Non-Random Passphrases

In March 2017, it was brought to my attention that the passphrases generated on the Preview tab of the KeePass Generate Password screen were not random.

Subsequent analysis showed that all passphrases generated by the plugin since Feb 2013 have a very high probability of being duplicates. That is, if you run KeePass multiple times and generate passphrases, they will generate the same passphrases each time. These duplicates are possible across different KeePass databases, operating systems and even computers from around the world.

If you generated a passphrase from the Readable Passphrase Generator plugin in KeePass in the last 4 years, I highly recommend you change that passphrase to a new one.

Passwords generated from https://makemeapassword.ligos.net are not affected.

Passwords generated from the console (command line) generator are not affected.

All users should upgrade to version 0.17.0 or newer as soon as possible.

Affected versions

ReadablePassphraseGenerator KeePass Plugin: 0.11.0 (released 21st Feb 2013) through to 0.16.0

Possible mitigating factors

  • The first passphrase generated was always random.
  • If you used non-default configuration, your passphrases will be different to other people's, albeit with insufficient randomness.
  • Changes in the dictionary over time will mean the passphrases generated would have changed, albeit with insufficient randomness.
  • Changes in the behaviour of KeePass's random number generator over the years may reduce the impact (but I'm assuming the worst case).

Technical details

The bug is a result of inadvertently re-using the random number generator supplied by KeePass to all plugins. The first passphrase generated is truly random, but the subsequent passphrases are not random.

KeePass gives a new CryptoRandomStream to a plugin each time it generates a passphrase (and it generates around 25 samples on the Preview tab). After each passphrase is generated, the CryptoRandomStream is disposed and the internal state set to all zeros. Caching of this disposed CryptoRandomStream and subsequent re-use means the random number generator always generates the same sequence of numbers, and thus the same passphrases. The same passphrases are generated, even on totally different and unrelated computers.

The caching behaviour was added because there was significant performance impact when loading the dictionary for every passphrase generated. Unfortunately, the caching behaviour inadvertently kept the CryptoRandomStream, even after KeePass disposed of it.

The disposed CryptoRandomStream did not provide any indication (via error codes or exceptions) that it was disposed, and thus continued to produce apparently random numbers. The CryptoRandomStream is a fast pseudo-random generator (although entirely suitable for generating passwords), and when its internal state is set to zero, it produces exactly the same sequence of numbers.

Update: From KeePass 2.36 onwards (unreleased this time), the CryptoRandomStream throws an ObjectDisposedException after it is disposed. This will cause affected versions of the plugin to crash KeePass when you generate passphrases which may be duplicates. That is, KeePass 2.36 prevents this bug and prevents the duplicate passphrases. You must upgrade to version 0.17 to safely use the plugin.

The fix was to cache the dictionary only, and use a new CryptoRandomStream for each passphrase generation.

Passphrases generated from https://makemeapassword.ligos.net and the console generator are not affected as a different random number generator is used.

I'm Sorry

Apologies for the dramas this will (and has) caused people.

Murray