To illustrate the Public API, I'll reproduce the examples from How to Use the Console App in C#.

A Single Phrase

The simplest possible usage to generate a single passphrase is as follows:
var generator = new ReadablePassphraseGenerator();    // New up the generator.
var loader = new ExplicitXmlDictionaryLoader();    // New up the xml dictionary loader.
var dict = loader.LoadFrom();    // Load the default dictionary.
generator.SetDictionary(dict);    // Set the default dictionary.
var phrase = generator.Generate(PhraseStrength.Random);    // Generate a phrase.

And if you want to calculate the combinations like the console app did:
var combinations = generator.CalculateCombinations(PhraseStrength.Random);    
var min = combinations.Shortest;
var max = combinations.Longest;
var weightedAvg = combinations.OptionalAverage;
// Each of the above properties has a related one ending in AsEntropyBits as well.

(More information about Counting Combinations).

Stronger Phrases

To generate phrases of different strength, choose a different PhraseStrength enum value.
var phrase = generator.Generate(PhraseStrength.Normal);    // Generate a phrase.

The generate method takes an overload for custom strengths: an IEnumerable<Clause>. Each PhraseStrength enum corresponds to a particular collection of Clause objects. You can see exactly what they look like in the static Clause.CreatePhraseDescription() methods. And you can parse a textual version an IEnumerable<Clause> using the static Clause.CreateCollectionFromTextString() method (see Custom Phrase Description for this textual format).
var phraseDescription = Clause.CreateCollectionFromTextString( ... );
var phrase = generator.Generate(phraseDescription);    // Generate a phrase.

And for multiple phrases you'll need to use an extremely advanced feature of C#: a loop.
for (int i = 0; i < 10; i++)
    var phrase = generator.Generate(PhraseStrength.Normal);

Random Phrases

Each of the PhraseStrength.Random... items correspond to a collection of base PhraseStrengths. One is chosen at random before using the normal logic to build a clause. You can find out what those mappings are in the PhraseDescription.Clause.RandomMappings static dictionary. They are based on the average length of the generated phrases by each PhraseStrength.

You can also define your own custom random strengths by selecting your own combination of PhraseStrength values and passing them to ReadablePassphraseGenerator.Generate(IEnumerable<PhraseStrength>) overload like so:
// New up a generator and load a dictionary as above.
var options = new [] {
    // And so on.
var phrase = generator.Generate(options);    // Generate a phrase based on one of the options provided.


There are only a few methods on the generator. Most have overloads to choose between a PhraseStrength enum and IEnumerable<Clause>.
public sealed class ReadablePassphraseGenerator
    // This has overloads for files and streams.
    public void LoadDictionary(dictionaryLoader, arguments) ...
    // This returns a bool and exception information rather than throwing.
    public bool TryLoadDictionary(dictionaryLoader, arguments, out exception) ...
    // Finally, if you manually load a dictionary from your own loader, this allows you to set it.
    public void SetDictionary(WordDictionary words)

    // This returns a 3 doubles representing the min, max and average combinations for a particular phrase strength.
    public PhraseCombinations CalculateCombinations() ....

    // Generates a passphrase as a string, in a StringBuilder. Fastest and lest secure.
    public String Generate() ....
    // Generates a passphrase as a SecureString. Slowest and most secure.
    public SecureString GenerateAsSecure() ....
    // Generates a passphrase as a UTF8 byte[]. Only slightly slower than Generate(), but the string is still unencrypted.
    public byte[] GenerateAsUtf8Bytes() ...

There are three variations of Generate(). One returns a normal string, one a SecureString, and the final one a UTF8 encoded byte[] .

The secure version builds the final passphrase in the SecureString character by character; the phrase is never visible as an unencrypted string. (Although, the dictionary words are stored in memory as unencrypted strings). This secure version is used by the KeePass plugin under Windows.

The standard one is used by the console app (since the passphrase will be visible on the console anyway!).

The UTF8 version builds the phrase as UTF8 encoded characters in a List<byte> and returns the final result as a byte[] . This allows you to deterministicly overwrite the resulting characters with zeros when you're finished with it, but the passphrase is still unencrypted. The UTF8 version is used by the KeePass plugin under non-Windows operating systems (such as Linux) as I've observed corruption when using the secure version.

My Random is Better Than Yours

The usefulness of any password or passphrase is entirely dependent on its random number generator. By default, the generator uses RNGCryptoServiceProvider. But you can pass a different one into its constructor. You must inherit RandomSourceBase and override byte[] GetRandomBytes(int numberOfBytes) which produces some number of random bytes (this should be trivial for any low level random number generator). The KeePass plugin uses KeePass's CryptoRandomStream instead.

For all the gory details of how to use the API, look at the console app or the test app (which counts words, combinations, does a couple of short benchmarks, dumps some statistics and more).

Last edited May 9, 2013 at 11:10 AM by ligos, version 11


No comments yet.