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.
Simple!
(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 [] {
PhraseStrength.Normal,
PhraseStrength.Strong,
PhraseStrength.Insane,
// And so on.
};
var phrase = generator.Generate(options); // Generate a phrase based on one of the options provided.
API
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).