Of course some files are plain text so it makes sense to introduce a modifier. This is a text string which is repeatedly Exclusive Ored, byte by byte against the bytes of the file. To make it even more secure, you can start reading the bytes from the file anywhere, just specify an offset from the start of the file.
A typical password might look like this
; >&1,'0 0. *), !%0!%7 2!+#-*'6/$.;A!2*-*.0"5C4"&<0'61%B>/?0*.0"5C4-*0*50%+
This is very easy to implement in C# so I present the password utility here. It includes all of source code and solution project files. I've omitted the exes which are zipped up here. It uses a couple of features of C# 2.0. I wrote and tested it in Microsoft Visual C# 2005 Express Edition.
How It WorksJust click the Select File button (or manually copy a file path into the File Edit Box. Click the Generate button and a password will be generated from the file you selected. You can type in a text modifier into the Modifier edit box (any text, the longer the better) and also a numeric offset into the file. This is how many bytes in from the start of the file to read.
The class FormLPG does all the work. There are event handlers for all three buttons. Click the Select File button and the OpenFileDialog provides the full path and filename which is copied into the File Edit Box. The class FileInfo is a handy way to get the size of the file and this code demonstrates that even an expression is an object with an inherited ToString() method!
The event handler for btnGenerate_Click does most of the donkeywork. First is an error check to verify the file actually exists. This uses the method File.Exists. This class in System.IO provides lots of useful routines for file copying, reading attributes etc. These are static methods which means you can use them directly by calling File.Method instead of having to create an instance of the class.
label3.Text = "Offset Maximum = " + (f.Length - 80).ToString();
MessageBox is a handy way of popping up error messages. There are 20 different overloaded versions of it provided in C#- this one uses two strings and displays the first string in a box with the caption set from the second string.
This next bit is a little complicated. First it creates a FileStream from the filename provided. If the numeric value in Offset is greater than zero then the file stream pointer moves to this offset (from the beginning of the stram). The enum SeekOrigin.Begin determines what the offset is relative to. You can move it relative to the current position or even so many bytes from the end.
Having got our filestream positioned where we want to read from it, we now use a BinaryReader object to read bytes into a byte array Buffer, up to the limit defined by the constant MaxLen. A Binary Reader object can extract values from as stream into whatever format you desire- bytes, doubles, ints, chars etc
Next we use a StringBuilder object EncStr to build up the output string. In C# strings are immutable- attempts to modify them, forces a copy to be made which is quite inefficient. A StringBuilder gets around this. By using Buffer.Length as the size of the StringBuilder we deal with the situation where the file we picked was a little lacking in bytes. Pick a 40 byte file and you get a 40 character password.
Now we loop through the Buffer bytes, clearing the top bit and if a modifier is provided we xor it character by character with the current byte. C# is quite strict about conversion so System.Convert.ToByte() takes a 16 bit character, out of the modifier string and converts it to an 8 bit byte.
Next, if the value is below 32 (and thus not really the type of character you want in a password string), we or it with 32. Finally we convert it to a char and append to EncStr.
The last three lines just display the password (it's a read-only Text Box) and copy the string to the clipboard.
ConclusionFrom trying this with many files I've come to the conclusion that text files give better passwords, paradoxically than binary. This is because binary files, especially exes and dlls often contain a lot of empty space which is zeros. Of course you can offset further into the file.
The main benefit of this is that it allows you to create very long passwords and know you can regenerate them if you lose the original. All you need is the file and the optional modifier and offset.
There's a Delphi version of An Easy Way to Generate Strong Passwords as well. You might recognize the author's name!
Back to How Tos