Click here to Skip to main content
15,885,546 members
Articles / Programming Languages / C#

A utility to read, edit, encrypt, decrypt, and write XmlStore files

Rate me:
Please Sign up or sign in to vote.
4.55/5 (9 votes)
12 Mar 2007CPOL9 min read 58.9K   1.3K   74   10
A utility to read, edit, encrypt, decrypt, write XmlStore files.

Screenshot - XmlStore.png

Introduction

Large data sets are best stored in databases. For small, simple, single-table datasets, a traditional database can be overkill, and it may be more convenient to store it in various simpler formats ranging from tab-delimited files to XML files. However, each one also brings its own complications, which are not addressed here.

XmlStore is intended to be a "no brainer" format. (More on this later.)

XmlStoreClient is a WinForms client with a simple user interface. It displays the contents of any XmlStore file in a DataGridView. You can navigate to any record (row) or field (column), edit it, and save your changes. You can also encrypt and decrypt:

  • an individual cell,
  • an entire row,
  • an entire column, or
  • the entire data set (table).

The Title column is encrypted in the picture above, and shown decrypted in the picture below.

Application Screen Shot

Warning

If you encrypt anything which requires you to supply a password, you will need the same password to decrypt the data. You have to remember it, as the password is not stored anywhere.

Background

Situation

A friend needed a simple utility to store usernames and passwords to some of the websites she visits often. Like a lot of people, she has a hard time remembering all the usernames and passwords she creates. She looked at solutions that could meet her needs, such as KeePass. But she was wary of getting a solution from an unfamiliar source. So, she wanted:

  1. an easy-to-use interface (as in "don't make me think") and
  2. a portable yet secure storage method, one that she could store on her memory stick and use from any of the several PCs she has access to at work, at home, on the road, etc.

Complication

As with any application being "custom-built" for someone, the requirements change. In this case, she first wanted only a simple list of usernames and passwords. Then, she wanted to add the name of the entity (e.g., bank), then she wanted to add its URL, and so on. This essentially became a third requirement -- the ability to add another field easily, without requiring a software update.

As this was a "gratis" assignment, I didn't want to have to maintain/update the utility each time she changed her list of "required fields".

I should mention, though, she did send in a nice donation to one of my favorite charities: Year Up. Indeed, if this utility or any of the code in it helps you, please consider sending a suitable donation to Year Up or to any similar organization in the world selflessly doing good work and helping people in need.

Solution

The DataGridView-based interface works well for my friend, because she is familiar with spreadsheets. For the second goal, the portable part is accomplished using XML and the secure part by allowing her to encrypt any "value" in the XML using yet another password, but one that:

  1. is not stored anywhere, except in her head, and
  2. one she can change any time, and as often as she wants.

The picture below shows a screenshot of a disguised variation of what she was happy with.

Application Screen Shot

Using the code

DISCLAIMER

I undertook this project to help a friend and, in the process, also learned a few things about Visual Studio 2005, C#, XML, DataGridView, cryptography, etc. Caveat Emptor: Nothing has been properly or adequately tested. More importantly, there is a good chance you or someone else can do this better. So if you do use this code and cannot decrypt something, there is little I or anyone can do to help you. On the bright side, though, since you have the source code, you can make it more bullet-proof to suit your needs.

Building the utility

If you have Visual Studio 2005, then you should be able to use the project source code "out of the box" -- simply build and run. The code itself is not rocket science. It is reasonably documented. If you don't have Visual Studio 2005, you will have to ask a more experienced friend. (Don't ask me, as I don't have a clue! Don't ask Microsoft either, as no one there will respond!!!)

Code modules

Side benefits of the code for newbies (like myself): the project includes modules with reasonably documented and self-explanatory code. With luck, they may help you learn how to use a few features of the various technologies employed.

VVX_About.cs

VVX.About is a simple class that provides a "cheap", zero maintenance, "Help | About" message box. If you don't know how to access information in an assembly, it can show you one way of extracting some information from it.

VVX_MsgBox.cs

VVX.MsgBox is a class to simplify access to MessageBoxes of different kinds. It helped me learn how to use message boxes more efficiently. For example, the MsgBox.Confirm(...) method allows me to do something like this:

C#
if (VVX.MsgBox.Confirm("Save changes?"))
    this.DoFileSave();

instead of this:

C#
if(DialogResult.Yes == MessageBox.Show("Save changes?", "Confirm", 
            MessageBoxButtons.YesNo, MessageBoxIcon.Question))
    this.DoFileSave();

VVX_FileDialog.cs

VVX.FileDialog is a class to access OpenFileDialog and SaveFileDialog a little more efficiently. For example, the FileDialog.GetFilenameToOpen(...) method allows me to do something like this:

C#
string filename = VVX.FileDialog.GetFilenameToOpen(VVX.FileDialog.FileType.XML);
if (filename.Length > 0)
{
    this.DoGridPopulate(this.ctlTableDGV);
}

The method simply takes care of setting up the filters, etc.

VVX_File.cs

VVX.File is a class to simplify access to a few dile-related methods, such as Delete. Again, it is not rocket science, but I found it was hard to remember that you have to use the System.IO.FileInfo class to delete a file! I can now delete a file with just this.

C#
VVX.File.Delete(sTempFile);

VVX_CryptoLib.cs

VVX.CryptoLib is a C# class that is a subset of and inspired by a VB-based CodeProject article: ".NET cryptography library for files and strings" by HanreG. I simply rewrote the code in C# and used only two methods:

  • public string EncryptString(string value , string password) {...}
  • public string DecryptString(string value , string password) {...}

For more information on these topics, see that article.

VVX_XmlStore.cs

VVX.XmlStore is a C# class that helps us "access" and "manage" an XmlStore file. Currently, it is geared to connect the data with the UI (DataGridView).

XmlStore

Consider the following "table":

Application Screen Shot

The XmlStore file for the above "table":

  • is essentially a simple "flat" XML file.
  • it stores the "tabular" data, for one table, such as the one for Passwords shown above.

and it looks like this:

XML
<?xml version="1.0" encoding="utf-8"?>
<xmlstore version="1.0">
  <schema datanodename="record">
    <field name="entity"   title="Entity" />
    <field name="username" title="Username" />
    <field name="password" title="Password" />
    <field name="url"      title="URL" />
    <field name="contact"  title="Contact" />
    <field name="phone"    title="Phone" />
  </schema>
  <record entity="bank" username="victorbox" password="Sony1234" 
          url="www.xyz.com" contact="john doe" phone="123-456-7890" />
  <record entity="city" username="victorboz" password="2MuchTax"
          url="www.city.gov" contact="Jane Doe" phone="890-456-1234" />
  <record entity="CodeProject" username="victorbos" password="goodguys"
          url="www.CodeProject.com" contact="-" phone="-" />
</xmlstore>

As you can see, it really is a plain XML file with:

  • a root node called xmlstore (but it can be named anything, because it is not directly referenced anywhere in the code).

and two types of "first-generation" child nodes within the root, namely,

  • a single <schema ... /> node, and
  • one data node for each row (or <record ... />) in the table.

The data node can have any base name; in the above example, it is named record.

The utility will work without a Schema node

The schema node is nice to have, but not necessary. If it is not found, VVX.XmlStore will simply enumerate the attributes in the first data (e.g., <record ... />) node and use the names of the attributes as the titles of the columns.

About the Schema node

The schema node serves a limited purpose. First, it provides the display title (i.e., column header) shown in the DataGridView for each column whose values come from a corresponding attribute in the data (i.e., record) nodes.

Second, its datanodename attribute identifies the base name, "record", of the data nodes; in this example, <record ... />.

Important

It is likely very obvious to you, but just in case it is not ...

  1. The schema node must be <schema ... />; do not change its base name.
  2. Its attribute must be named as shown: <schema datanodename="..." >; do not change its name.
  3. Its child nodes must be <field name="..." title="..." />; do not change their base name or attribute names.
  4. If you change the base name of the data nodes from <record ... /> to, say, <lulu ... />, then you must also change the value of the datanodename attribute from "record" to "lulu".
  5. If you change the name of an attribute in the data node, you should also change its name in the corresponding <field ... /> node. For example, if you change <record entity="bank" ... /> to <record vendor="bank" ... />, then you should change <field name="entity" title="Entity" /> to <field name="vendor" title="Entity" />. Note: Changing the title is entirely cosmetic.

Why bother with XmlStore?

After reading the last part, you may feel this is too much of a headache. In my opinion, for this utility, these "rules" are perhaps a little less demanding than some of the alternatives.

Actually, you can do all of this by using a System.Data.DataTable and its ReadXml and ReadXmlSchema methods and then writing the necessary code to initialize the DataGridView. The limitation of such an approach, for this utility anyway, is that my friend would have to maintain two files, one for the XML and one for the schema; for non-geeks, having to do so more than doubles the complexity of the solution. Besides, I may not have learned as much as I did!

Improvements needed

There is plenty of room for improvement: an easier way to "test" and "repair" an XmlStore file; an easier way to create a new file; an easier way to change the Crypto password; an easier way to rearrange the columns. My friend doesn't really want/need these ... but they reflect the obvious limitations of this utility.

If you need something more "powerful" and "rich" ...

If this utility is too wimpy for you, one of the following may suit you better:

Unfortunately, they are a little too complicated for my friend. (Recall one of the requirements was "don't make me think"!)

Finally, a word of thanks to you

I have learned a lot from people like you who have anonymously and freely shared your experiences with the world. Perhaps, you gave a little, but I learned a lot. If this utility helps even one person, you've made my day and given me a chance to give back to the community. So, thank you!

Other recent contributions

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
An old dog trying to learn new tricks!

Comments and Discussions

 
QuestionHi Pin
taha 20102-Feb-12 12:06
taha 20102-Feb-12 12:06 
AnswerRe: Hi Pin
victorbos2-Feb-12 12:16
victorbos2-Feb-12 12:16 
Generalvery good Pin
chenlulouis28-Jun-10 21:27
chenlulouis28-Jun-10 21:27 
GeneralRe: very good Pin
victorbos1-Jul-10 5:35
victorbos1-Jul-10 5:35 
NewsTwo other related encryption articles in CodeProject ... Pin
Tony Selke27-Sep-07 6:51
Tony Selke27-Sep-07 6:51 
QuestionWhy not DataSet? Pin
Vitali Brusentsev23-Mar-07 23:28
Vitali Brusentsev23-Mar-07 23:28 
AnswerRe: Why not DataSet? Pin
victorbos24-Mar-07 6:04
victorbos24-Mar-07 6:04 
GeneralDataGridView Printing XmlStore data Pin
victorbos19-Mar-07 0:54
victorbos19-Mar-07 0:54 
In XmlStore Part 2[^]added support for printing the contents of a DataGridView
GeneralFile.Delete Pin
Steve Hansen12-Mar-07 21:19
Steve Hansen12-Mar-07 21:19 
GeneralRe: File.Delete [modified] Pin
victorbos13-Mar-07 2:18
victorbos13-Mar-07 2:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.