G
Guest
I am using a CryptoStream to encrypt and then save an xml file. However,
when reading it back in, I am getting a CryptographicException. I am hitting
this because I have some large xml files ( > 10MB) and I only need a certain
node...I use an XmlTextReader to find the node I need, and then attempt to
abort reading in the rest of the xml, but when I close the XmlTextReader I
get the exception. I've included some sample code and xml that should
exhibit the behavior.
Note: If I use Skip() to get to the end of the xml, then I don't get
exceptions, but as I mentioned, the files I'm dealing with can be large and
Skip() takes quite a while to skip over nodes that I don't care about which
really hurts performance. Any ideas?
--------- SAMPLE SOURCE CODE ---------
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;
using System.Xml;
private const string MY_PASSWORD = "test"; private const string
SOURCE_XML_FILE_PATH = @"C:\Sample.xml"; private const string
ENCRYPTED_FILE_PATH = @"C:\Sample.xmle";
static void Main(string[] args)
{
EncryptFile(SOURCE_XML_FILE_PATH, ENCRYPTED_FILE_PATH, MY_PASSWORD);
ReadEncryptedXml(ENCRYPTED_FILE_PATH, MY_PASSWORD); }
private static void ReadEncryptedXml(string encryptedFilePath, string
password) {
FileStream fileStreamSrc = null;
CryptoStream cstream = null;
StreamReader streamReader = null;
XmlTextReader xmlReader = null;
try {
fileStreamSrc = new FileStream(encryptedFilePath, FileMode.Open,
FileAccess.Read);
cstream = CreateEncryptedStream(fileStreamSrc, password,
CryptoStreamMode.Read);
streamReader = new StreamReader(cstream, Encoding.UTF8);
xmlReader = new XmlTextReader(streamReader);
xmlReader.WhitespaceHandling = WhitespaceHandling.None;
xmlReader.MoveToContent();
bool breakOut = false;
while (xmlReader.NodeType != XmlNodeType.EndElement) {
switch (xmlReader.Name) {
case "States":
xmlReader.Read();
break;
case "State":
xmlReader.Read();
break;
case "Name":
xmlReader.Skip();
break;
case "Population":
XmlDocument retValue1 = new
XmlDocument();
retValue1.AppendChild(
retValue1.ReadNode( xmlReader ));
breakOut = true;
break;
default:
xmlReader.Skip();
break;
}
if (breakOut) {
break;
}
}
xmlReader.Close();
streamReader.Close();
cstream.Close();
fileStreamSrc.Close();
}
catch (CryptographicException ex) {
Console.WriteLine(ex.ToString());
}
catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
}
private static void EncryptFile(string sourceXmlFilePath, string
destEncryptedFilePath, string password) {
FileStream fileStreamSrc = null;
FileStream fileStreamDest = null;
CryptoStream cstream = null;
try {
fileStreamSrc = new FileStream(sourceXmlFilePath, FileMode.Open,
FileAccess.Read);
fileStreamDest = new FileStream(destEncryptedFilePath, FileMode.Create,
FileAccess.Write);
long rdlen = 0;
long totlen = fileStreamSrc.Length;
int len;
cstream = CreateEncryptedStream(fileStreamDest, password,
CryptoStreamMode.Write);
// Read from input file, encrypt and write to output file
byte[] b = new byte[1024];
while(rdlen < totlen) {
len = fileStreamSrc.Read(b, 0, b.Length);
cstream.Write(b, 0, len);
rdlen = rdlen + len;
}
cstream.Close();
fileStreamDest.Close();
fileStreamSrc.Close();
}
catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
}
private static CryptoStream CreateEncryptedStream( Stream baseStream, string
password, CryptoStreamMode streamMode ) {
CryptoStream retValue = null;
SymmetricAlgorithm cryptoAlgorithm = Rijndael.Create();
PasswordDeriveBytes pdb = new PasswordDeriveBytes( password,
new byte[]{
0x12, 0x34, 0x56,
0x78, 0x90,
0xAB,
0xCD, 0xEF,
0x10,
0x11, 0x22,
0x33,
0x44 });
cryptoAlgorithm.Key = pdb.GetBytes( 32 );
cryptoAlgorithm.IV = pdb.GetBytes( 16 );
if( streamMode == CryptoStreamMode.Read ) {
retValue = new CryptoStream( baseStream,
cryptoAlgorithm.CreateDecryptor(), streamMode );
}
else {
retValue = new CryptoStream( baseStream,
cryptoAlgorithm.CreateEncryptor(), streamMode );
}
return retValue;
}
private static void DecryptFile(string encryptedFilePath, string
destinationFilePath, string password) {
FileStream fileStreamSrc = null;
CryptoStream cstream = null;
try {
fileStreamSrc = new FileStream(encryptedFilePath, FileMode.Open,
FileAccess.Read);
cstream = CreateEncryptedStream(fileStreamSrc, password,
CryptoStreamMode.Read);
StreamWriter fsDecrypted = new
StreamWriter(destinationFilePath);
fsDecrypted.Write(new StreamReader(cstream).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
cstream.Close();
fileStreamSrc.Close();
}
catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
}
--------- SAMPLE XML ---------
<States>
<State>
<Name>Illinois</Name>
<Population>Unknown</Population>
<Data>
<Item type="MyType" number="1">
<SubItem utcTime="2004-09-12 17:00:00Z" timeTicks="632306052000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-12 17:00:00Z" timeTicks="632306052000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-12 20:15:00Z" timeTicks="632306169000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-12 20:15:00Z" timeTicks="632306169000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-12 20:15:00Z" timeTicks="632306169000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-13 00:30:00Z" timeTicks="632306322000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-14 01:00:00Z" timeTicks="632307204000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:05:00Z" timeTicks="632312211000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-20 00:30:00Z" timeTicks="632312370000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-21 01:00:00Z" timeTicks="632313252000000000"
attr1="False" attr2="False" />
</Item>
<Item type="MyType" number="2">
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:05:00Z" timeTicks="632312211000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-20 00:30:00Z" timeTicks="632312370000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-21 01:00:00Z" timeTicks="632313252000000000"
attr1="False" attr2="False" />
</Item>
</Data>
</State>
</States>
when reading it back in, I am getting a CryptographicException. I am hitting
this because I have some large xml files ( > 10MB) and I only need a certain
node...I use an XmlTextReader to find the node I need, and then attempt to
abort reading in the rest of the xml, but when I close the XmlTextReader I
get the exception. I've included some sample code and xml that should
exhibit the behavior.
Note: If I use Skip() to get to the end of the xml, then I don't get
exceptions, but as I mentioned, the files I'm dealing with can be large and
Skip() takes quite a while to skip over nodes that I don't care about which
really hurts performance. Any ideas?
--------- SAMPLE SOURCE CODE ---------
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;
using System.Xml;
private const string MY_PASSWORD = "test"; private const string
SOURCE_XML_FILE_PATH = @"C:\Sample.xml"; private const string
ENCRYPTED_FILE_PATH = @"C:\Sample.xmle";
static void Main(string[] args)
{
EncryptFile(SOURCE_XML_FILE_PATH, ENCRYPTED_FILE_PATH, MY_PASSWORD);
ReadEncryptedXml(ENCRYPTED_FILE_PATH, MY_PASSWORD); }
private static void ReadEncryptedXml(string encryptedFilePath, string
password) {
FileStream fileStreamSrc = null;
CryptoStream cstream = null;
StreamReader streamReader = null;
XmlTextReader xmlReader = null;
try {
fileStreamSrc = new FileStream(encryptedFilePath, FileMode.Open,
FileAccess.Read);
cstream = CreateEncryptedStream(fileStreamSrc, password,
CryptoStreamMode.Read);
streamReader = new StreamReader(cstream, Encoding.UTF8);
xmlReader = new XmlTextReader(streamReader);
xmlReader.WhitespaceHandling = WhitespaceHandling.None;
xmlReader.MoveToContent();
bool breakOut = false;
while (xmlReader.NodeType != XmlNodeType.EndElement) {
switch (xmlReader.Name) {
case "States":
xmlReader.Read();
break;
case "State":
xmlReader.Read();
break;
case "Name":
xmlReader.Skip();
break;
case "Population":
XmlDocument retValue1 = new
XmlDocument();
retValue1.AppendChild(
retValue1.ReadNode( xmlReader ));
breakOut = true;
break;
default:
xmlReader.Skip();
break;
}
if (breakOut) {
break;
}
}
xmlReader.Close();
streamReader.Close();
cstream.Close();
fileStreamSrc.Close();
}
catch (CryptographicException ex) {
Console.WriteLine(ex.ToString());
}
catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
}
private static void EncryptFile(string sourceXmlFilePath, string
destEncryptedFilePath, string password) {
FileStream fileStreamSrc = null;
FileStream fileStreamDest = null;
CryptoStream cstream = null;
try {
fileStreamSrc = new FileStream(sourceXmlFilePath, FileMode.Open,
FileAccess.Read);
fileStreamDest = new FileStream(destEncryptedFilePath, FileMode.Create,
FileAccess.Write);
long rdlen = 0;
long totlen = fileStreamSrc.Length;
int len;
cstream = CreateEncryptedStream(fileStreamDest, password,
CryptoStreamMode.Write);
// Read from input file, encrypt and write to output file
byte[] b = new byte[1024];
while(rdlen < totlen) {
len = fileStreamSrc.Read(b, 0, b.Length);
cstream.Write(b, 0, len);
rdlen = rdlen + len;
}
cstream.Close();
fileStreamDest.Close();
fileStreamSrc.Close();
}
catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
}
private static CryptoStream CreateEncryptedStream( Stream baseStream, string
password, CryptoStreamMode streamMode ) {
CryptoStream retValue = null;
SymmetricAlgorithm cryptoAlgorithm = Rijndael.Create();
PasswordDeriveBytes pdb = new PasswordDeriveBytes( password,
new byte[]{
0x12, 0x34, 0x56,
0x78, 0x90,
0xAB,
0xCD, 0xEF,
0x10,
0x11, 0x22,
0x33,
0x44 });
cryptoAlgorithm.Key = pdb.GetBytes( 32 );
cryptoAlgorithm.IV = pdb.GetBytes( 16 );
if( streamMode == CryptoStreamMode.Read ) {
retValue = new CryptoStream( baseStream,
cryptoAlgorithm.CreateDecryptor(), streamMode );
}
else {
retValue = new CryptoStream( baseStream,
cryptoAlgorithm.CreateEncryptor(), streamMode );
}
return retValue;
}
private static void DecryptFile(string encryptedFilePath, string
destinationFilePath, string password) {
FileStream fileStreamSrc = null;
CryptoStream cstream = null;
try {
fileStreamSrc = new FileStream(encryptedFilePath, FileMode.Open,
FileAccess.Read);
cstream = CreateEncryptedStream(fileStreamSrc, password,
CryptoStreamMode.Read);
StreamWriter fsDecrypted = new
StreamWriter(destinationFilePath);
fsDecrypted.Write(new StreamReader(cstream).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
cstream.Close();
fileStreamSrc.Close();
}
catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
}
--------- SAMPLE XML ---------
<States>
<State>
<Name>Illinois</Name>
<Population>Unknown</Population>
<Data>
<Item type="MyType" number="1">
<SubItem utcTime="2004-09-12 17:00:00Z" timeTicks="632306052000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-12 17:00:00Z" timeTicks="632306052000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-12 20:15:00Z" timeTicks="632306169000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-12 20:15:00Z" timeTicks="632306169000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-12 20:15:00Z" timeTicks="632306169000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-13 00:30:00Z" timeTicks="632306322000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-14 01:00:00Z" timeTicks="632307204000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:05:00Z" timeTicks="632312211000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-20 00:30:00Z" timeTicks="632312370000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-21 01:00:00Z" timeTicks="632313252000000000"
attr1="False" attr2="False" />
</Item>
<Item type="MyType" number="2">
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 17:00:00Z" timeTicks="632312100000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:05:00Z" timeTicks="632312211000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-19 20:15:00Z" timeTicks="632312217000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-20 00:30:00Z" timeTicks="632312370000000000"
attr1="False" attr2="False" />
<SubItem utcTime="2004-09-21 01:00:00Z" timeTicks="632313252000000000"
attr1="False" attr2="False" />
</Item>
</Data>
</State>
</States>