It might not be a common scenario, but anyway it happens - and you know how it is. Personally, I have two email accounts, lots of sites where I've registered, and much, much more. Time went by...
...And suddenly the amount of information to be remembered (the attempt in itself was completely unjustified) has reached some level when I had several mutually exclusive options:
- Forget everything - probably the easiest option, which, however, could cause a nervous breakdown or something...
- Write as much as I could remember on a noticeable orange (yellow, red...) piece of paper and hide it somewhere in a hope that I won't forget where I put it.
- Write all passwords and stuff in a Notepad file and either have it stolen or, according to Murphy's law, forget about it and remember only after pressing Enter in a format c: magic spell.
- Download some program. The easiest option, but for some reason (I admit that I didn't spend weeks searching for a a. Simple, b. Freeware and c. Secure program), I chose a somewhat different option, which is...
- Write my own password manager.
Of course, there must have been some great programs (hmmm...) doing the same job, but it was just quite interesting to write my own password manager for personal use (I actually haven't initially thought of posting it on The CodeProject), so here are the results of my work.
In the beginning, I've spent some time looking for a suitable encryption algorithm (at that time, I didn't even suppose that I'll also need a hashing algorithm - lack of planning and stuff...). I decided in favor of RC5 - a symmetric block cipher, which was said to be fast and secure. Initially, I wanted to write some kind of
CRC5 class but (mostly for the hell of it) I decided to turn it into a separate fancy-looking DLL with some kind of API (contexts, handles and so on...). Then I started to think about how the program itself will look like. The idea of storing User name and Master password in the password storage itself seemed perfidious, so I understood that some hashing algorithm is required and I fixed upon MD5, invented by the tireless Professor Ronald R. Rivest. As with RC5, a simple
CMD5 class turned into a standalone DLL. So here's what I decided to implement.
- Store a <User Name> + <Master Password> hash in a password storage and compare with the hash of <User Name> + <Master Password> entered when attempting to open a storage.
- Generate a private key by repeatedly hashing <User Name> + <Master Password> + <All Previous Hashes> so that knowing <User Name> + <Master Password> combination hash doesn't guarantee successful cracking.
- When loaded, all sensitive information remains encrypted until it is shown on the screen.
A few notes about the code and my style (in case anybody's interested). The core code is pretty straightforward and (hopefully) well commented - again, I originally had no intention to post it or whatever. It compiles clearly under Warning level 4 - well, except for the stupid C4786 warning with compiler choking on long names, but Release version should compile perfectly. I had no possibility (or maybe I felt too lazy) to test the program on platforms different from Windows 2000, and I think there are a few notes to be held in mind if you would like to launch it under, say, Windows 9x.
IDC_HAND resource (a cursor - see StaticHyperLinkEx.cpp) is, according to MSDN, a stock resource only for Windows 2000 and above, so take this into account - you might need to import some suitable cursor or something.
SS_ENDELLIPSIS style for static controls will work under Windows 9x - it is for Windows NT and later, so this code:
GetDlgItem(IDC_TITLE_TITLE)->ModifyStyle(0, SS_ENDELLIPSIS, 0);
should be either removed or altered somehow. And
PathCompactPathEx() requires Internet Explorer 4.0 for all platforms.
For some (obscure?) reason, usual User Interface Update stuff doesn't seem to be working in dialog-based applications, so I had to do menu items switching by calling
SwitchMenu() and passing some flags.
I wonder why Tree View does not support Drag-n-Drop natively - it was hell of a job to decipher the poorly written SDK documentation in order to implement this stuff.
And a few words about problems and "not-yet-implemented" things (except for the things above):
- Some flickering when either switching from Element to Element or switching from Hide Password to Show Password mode or vice versa. This is because of switching controls on and off, and I hope to fix it soon.
- Somehow inconvenient Password Generator as you have to move your mouse to generate a password - but on the other hand, it is not that bad...
- Unicode support hasn't been tested properly.
This section is more likely to be a feature list, but it is pretty much the same, I guess. So this is what we have for the moment:
- Fairly fast and lightweight program. The throughput of the cipher is the same for all key lengths less than 832 bits, so there are no performance reasons for choosing shorter keys.
- Reasonable level of security. For the time being, I saw no reviews or whatever about successful crypto-analysis of RC5. I can't say the same thing for MD5 as B. den Boer and A. Bosselaers succeeded in discovering collisions in this hashing algorithm (see "Collisions for the Compression Function of MD5" for detail), but this fact doesn't affect the overall security level.
- Native file format. This allows to do some shell-related tricks like opening storage by double-clicking... well, you know how it is.
- User's files hashing. This feature can be used to hash some users' files (or messages) to monitor their consistency and integrity.
- Password generator. This is not a huge novelty, but nevertheless it is quite a handy feature.
- Easy to use. Every function is clearly visible in the interface. Context menus in a tree control might not be so obvious, but they do exist (as well as hyperlinks within dialogs).
- Password security. Not an obvious notion, but the idea is quite simple. Security level can be greatly compromised by exposing the exact length of your passwords, so if you have, say, 6 characters in your password and you're in a Hide Password mode, the program displays 10 asterisks all the time.
- Some kind of Intelligent Context Menus (a fancy name, isn't it ;) ?). Menu items are not just switched on or off - instead, I'm loading totally different menus (with more convenient layout) when right-clicking on various parts of the tree to the left.
- Hot keys. Each element can be assigned a hot key, so password of the respective element is transferred directly to the currently focused window, but it is somewhat superseded with SmartType.
- Rated items. All items (both Categories and Elements) can be rated according to their importance.
- Shell extension. Provides a tool-tip with information about storage version and key size. Mostly for fun...
- XML Export. Just exports password storage to XML file. I'm now studying XSLT in order to create some fancy transformation.
- SmartType. The most interesting thing (at least I think so). By pressing a defined hot key, password and login are automatically transferred to a focused window without any hassle.
Here are a few more points in case anybody's interested (these are taken directly from Options dialog):
- Maintains File Associations
- Minimizes to Tray
- Create Backup Before Saving
- Auto Save on Exit
- Shell Open as Read Only
- Reload Last Storage
- Reload as Read Only
- Automatic Sorting
- Clipboard Erasing
Should you encounter any bugs or have any ideas - email me. All suggestions are greatly appreciated.
- 1.8 Build 1482 (5 March 2005)
- This is mostly for developers - added a new Project configuration (release with MFC statically linked) - inspired by alens.
- New executable (for those who don't have VS2003 installed) - somewhat bigger than the first one - here it is, gixxer600.
- Added Installer (thanks to Jordan Russell for InnoSetup).
- 1.8 Build 1482 (15 August 2004)
- MD5 Hash Generator is now fully RFC-compliant (thanks to Robin Schive for inspiration).
- Address field is hyperlinked.
- Icons are now in a separate DLL, so one can build a new one (thanks to Robin Schive and many others).
- 1.7 Build 1421 (15 July 2004)
- Removed the useless button on the main dialog - it looked truly awful under Windows XP.
- Ported to Visual C++ 2003 and there will be no further Visual C++ 6 versions.
- A few more points I can't really recall :)
- 1.7 Build 1372 (24 June 2004)
- Storages can now be opened in Read-Only mode.
- Backing up previous storage.
- A few new options.
- Saves settings to XML files.
- "Copy" command now works in all fields (quite a popular request).
- 1.5 Build 1156 (8 May 2004)
- SmartType feature (partly inspired by Garth J Lancaster).
- Export To XML is possible.
- A few UI fixes/improvements.
- 1.4 Build 867 (24 April 2004)
- Shell extension which displays Storage Version and Key Size in tooltip (thanks to Michael Dunn for a series of great articles).
- Ported to Visual Studio .NET 2003 (obviously not to C#).
- Right-click on Password link copies password to clipboard (thanks to metomas).
- Items can be Rated according to their importance (somewhat inspired by Orcrist).
- Items can be Sorted (both Categories and Elements).
- And finally, they can be Auto-sorted when adding.
- 1.2 Build 720 (19 April 2004)
- Fixed a bug in User's file hashing.
- Enter works as it has to in all "Notes" and "Descriptions" (thanks to zijan).
- 1.1 Build 713 (11 April 2004)
- "Minimize to tray " feature added.
- "Reload last storage on exit" feature added.
- "Auto-save storage on exit" is possible.
- Hot keys can be assigned to transfer passwords directly to destination windows.
- Storage options can be set up.
- File associations are maintained directly by the program.
- 1.0 Build 521 (4 April 2004) - Initial release.