 |
|
 |
I think a much easier and elegant way to handle this is to use the WriteXml and ReadXml methods of the dataset class, passing in as an argument a CryptoStream object (System.Security.Cryptography namespace). CryptoStream derives from Stream class so, the process is straightforward and pratically transparent to the dataset class.
source would look like:
public void Encrypt(DataSet ds, string filename) { outFile = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write); encryptStream = new CryptoStream(outFile, encryptor, CryptoStreamMode.Write); ds.WriteXml(encryptStream); encryptStream.Close(); outFile.Close(); }
public DataSet Decrypt(string filename) { DataSet result = new DataSet(); inFile = new FileStream(filename, FileMode.Open, FileAccess.Read); decryptStream = new CryptoStream(inFile, decryptor, CryptoStreamMode.Read); result.ReadXml(decryptStream); decryptStream.Close(); inFile.Close(); return result; }
encrypt and decryptor objects are defined as:
ICryptoTransform encryptor; ICryptoTransform decryptor; and can be obtained in different ways, depending on the programmer's choices. I suggest the fully managed RijndaelManaged.CreateEncryptor() and RijndaelManaged.CreateDecryptor() methods for symmetric encryption.
Hope this helps someone.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Great work! I've noticed only one problem with ReadEncryptedXML() - if you specify afile located elsewhere on the machine, it will fail. You should change this line:
inFile = new FileStream(fi.Name, FileMode.Open);
with the following
inFile = new FileStream(fi.FullName, FileMode.Open);
Thanks again
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I had to change line #173
//from:
inFile = new FileStream(fi.Name, FileMode.Open);
//to:
inFile = new FileStream(fi.FullName, FileMode.Open);
I needed to pass in the full path otherwise it would default to the application path (bin directory)
otherwise works great! thanks for doing the heavy lifting
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
 |
You may also be interested in looking at the following, related Code Project articles:
Generic SymmetricAlgorithm Helper[^] This is a generic helper class that exposes simplified Encrypt and Decrypt functionality for strings, byte arrays and streams for any SymmetricAlgorithm derivative (DES, RC2, Rijndael, TripleDES, etc.).
Making TripleDES Simple in VB.NET and C#[^] This is a simple wrapper class that provides an easy interface for encrypting and decrypting byte arrays and strings using the 3DES algorithm.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
I am using your code in a VB.NET project. I included your DLL. The code encrypts the file very well (apparently), as the file is the proper size. But it will not decrypt. I get Nothing as my data set.
Can I use any user name and password, or are there limitations?
Any other ideas as to how to debug the problem?
Thank you!
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
I found the first problem. In your source file at line number 171:
try { inFile = new FileStream(fi.Name, FileMode.Open); } catch (Exception exc)
should be:
try { inFile = new FileStream(fileName, FileMode.Open); } catch (Exception exc)
... otherwise, the routine can only fnd files in the current windows diretory. "fi.name" is just a file name, and ignores the path passed in by the user.
Now that I am beyond this minor glitch, the routine does not successfully deserialize. It produces a slightly corrupt data set. I am using an xsd file to determine column types, and those types are off. Also, some columns are missing.
Do you have rules for the user name and password? The length? The characters available for those two strings? Any other reason for this sort of problem?
Thank you!
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Hello,
Another problem I found is all fields in the xml decrypted file are type="xs:string" it won't keep original xml schema.
Is there a workaround to keep original schema.
Thank you in advance
Luis Mora
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi Luis,
This is entirely dependent on the XSD or dataset that was read in in the first place. The encryption/decryption is done at the file level, not at the schema/XML level. If your xsd schema contained int16 etc, it should come out normally.
If you have a sample xsd you want to share, I can test it out.
Koenraad
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hello,
I referenced your code in one of my projects and it worked just fine. Thank you very much !! It saved a lot of work.
I just have a little problem once I read an encrypted file using your function I really don't know how validate the null response in VB.net 2003 when it wasn't read properly
For example
Dim decryptor As New CryptoXML.XMLEncryptor("user", "password")
ds = decryptor.ReadEncryptedXML(ofdlg.FileName)
Here I don't know how to validate a null response as posted in this article.
Can you help ?
Luis
Luis Mora
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi Luis,
Sorry for the delay in getting back; I'm switching jobs & moving across the Atlantic, there has been little time for hobby programming!
Glad you found the code useful. I was a bit rusty on the details but here we go again:
In the ReadEncryptedXML() funton, you will find several checks, but they are mostly very basic (like passwords that are too small, file that don't exist, verifying the signature, etc). There is of course always the exception handler.
The check on whether a DataSet is valid, is entirely dependent on the code in lines 200-210:
// Read in the DataSet from the CryptoStream DataSet data = new DataSet(); try { data.ReadXml(csDecrypt, XmlReadMode.Auto); } catch (Exception exc) { Trace.WriteLine(exc.Message, "Error decrypting XML"); return null; }
One can dump additional data from the Exception, but that's probably as far as it gets. It's essentially the same mechanism that .NET uses when you load an unencrypted dataset, not more, no less.
Hope this helps Koenraad
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
perhaps you could outline more how the encryptiong / decryption takes place? (esp. since that is the main feature of the code)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
The encryption/decryption starts by creating an algorithm, I used a symmetric algorithm called RijndaelManaged.
>> RijndaelManaged rijn = new RijndaelManaged();
The algorithm then creates a decryptor, using the key and IV byte[] arrays (these byte[] arrays are created during the construction of the CryptoXML object, see GenerateKey() and GenerateIV() functions).
>> ICryptoTransform decryptor = rijn.CreateDecryptor(md5Key, md5IV);
Following this, there is a sequence of events to manipulate the encrypted data. 1. I read the encrypted file into a byte[] buffer. 2. From the byte[] buffer, I can subsequently create a MemoryStream object. 3. The MemoryStream is then read by the decryptor into a CryptoStream object 4. The CryptoStream object, which now contains decrypted data, can be read by a newly created DataSet to read in the XML part of the data.
The code is somewhat compplicated by the fact that the unencrypted signature header needs to be handled as well.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
From quickly browsing the article and not trying the code yet it appears that you could take a dataset generated from any datasource, not just XML, to create the encrypted XML dataset. Am I correct in this assumption?
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Potentially, yes. But the ReadXML method is the only DataSet method that reads files/streams into the DataSet. I never had to work with servers so I would not know how to get there. The code in my article would probably need extensive change to deal with this possibility.
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |