Solved

Encrypting/Scrambling an XML file.

Posted on 2004-03-22
8
636 Views
Last Modified: 2008-03-17
Does anyone have code or know how to encrypt or scramble an XML file.  It doesn't have to be high security, just so that someone can't dbl click the XML file and read it.

0
Comment
Question by:UberDeveloper
8 Comments
 
LVL 6

Expert Comment

by:gtvingo14
Comment Utility
UberDeveloper,

W3.org wrote a book on XML file encryption, well actually few dosen pages
http://www.w3.org/TR/xmlenc-core/

or if you want to save time reading it, following link will show you how to encrypt a xml file
http://www-106.ibm.com/developerworks/xml/library/x-encrypt/listing2.html

0
 
LVL 28

Accepted Solution

by:
iboutchkine earned 500 total points
Comment Utility
1 interface, 3 classes  and 1 form

1.Interface ISXMLCipherKey.vb (create as class)
----------------------------------------------------------------
Imports System

Public Interface ISXMLCipherKey

    ReadOnly Property CipherKey() As Byte()
    Sub CipherKeyFinalize()

End Interface

=======================================================
2.Class SecureXML.vb
----------------------------------------------------------------
Imports System
Imports System.Xml
Imports System.IO
Imports System.Security.Cryptography

Public Structure SXMLDataHeader
    Public token As Int32
    Public Length As Int32
End Structure

Public Class SecureXML
    Implements IDisposable

    Public Const SXML_DATAHEADER_TOKEN As Int32 = &H190298

    Private _ciphertext As MemoryStream
    Private _cipherkey As ISXMLCipherKey
    Private _cipherIV As Byte() = {&HA1, &HFF, &H1F, &H22, &HF0, &HBB, &HBF, &HFB, &HCB, &H9A, &H2C, &H87, &H0, &HF, &H7D, &HDC}

    Public Sub New(ByVal cipherkey As ISXMLCipherKey)
        _ciphertext = New MemoryStream
        _cipherkey = cipherkey
    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose
        _ciphertext.SetLength(0)


        _ciphertext = Nothing
        _cipherkey = Nothing
    End Sub

    Public Sub Save(ByVal xmldoc As System.Xml.XmlDocument, ByVal output As Stream)
        Dim alg As New RijndaelManaged
        Dim encryptor As ICryptoTransform
        Dim streamwriter As New BinaryWriter(output)
        Dim headerinfo As New SXMLDataHeader
        Dim cipherStream As CryptoStream

        _cipherkey.CipherKeyFinalize()
        alg.Key = _cipherkey.CipherKey
        alg.IV = _cipherIV
        encryptor = alg.CreateEncryptor()

        cipherStream = New CryptoStream(_ciphertext, encryptor, CryptoStreamMode.Write)
        'Save XML Encrypted
        xmldoc.Save(cipherStream)

        'Flush Our CipherStream Data to our CipherText Stream
        cipherStream.FlushFinalBlock()

        headerinfo.token = SXML_DATAHEADER_TOKEN
        headerinfo.Length = _ciphertext.Length

        'Output our header info to the output stream
        WriteHeader(headerinfo, streamwriter)
        'Write Our CipherText to the end of the output stream
        _ciphertext.WriteTo(output)

        'Reset for next use
        Reset()
    End Sub

    Public Function Load(ByVal input As Stream) As System.Xml.XmlDocument
        Dim streamreader As New BinaryReader(input)
        Dim headerinfo As SXMLDataHeader
        Dim alg As New RijndaelManaged
        Dim encryptor As ICryptoTransform
        Dim cipherStream As CryptoStream

        Dim xmldoc As New System.Xml.XmlDocument

        If Not ReadHeader(headerinfo, streamreader) Then
            Return Nothing
        End If

        'Buffer the data from the input stream into our ciphertext stream
        _ciphertext.Write(streamreader.ReadBytes(headerinfo.Length), 0, headerinfo.Length)

        'Seek to the beginning of the ciphertext stream
        _ciphertext.Seek(0, SeekOrigin.Begin)

        'Init Decryption Alg
        _cipherkey.CipherKeyFinalize()
        alg.Key = _cipherkey.CipherKey
        alg.IV = _cipherIV
        encryptor = alg.CreateDecryptor()

        cipherStream = New CryptoStream(_ciphertext, encryptor, CryptoStreamMode.Read)

        'Load our unencrypted XML Data
        xmldoc.Load(cipherStream)

        'Reset for next use
        Reset()

        'Return the new XML Doc to the user
        Return xmldoc
    End Function

    Private Sub WriteHeader(ByVal header As SXMLDataHeader, ByVal output As BinaryWriter)
        output.Write(header.token)
        output.Write(header.Length)
    End Sub

    Private Function ReadHeader(ByRef header As SXMLDataHeader, ByVal input As BinaryReader) As Boolean
        Dim hdr As New SXMLDataHeader

        hdr.token = input.ReadInt32()

        If hdr.token <> SXML_DATAHEADER_TOKEN Then
            Return False
        End If

        hdr.Length = input.ReadInt32()

        If hdr.Length <= 0 Or hdr.Length > (input.BaseStream.Length) Then
            Return False
        End If

        header = hdr
        Return True
    End Function

    Public Sub Reset()
        _ciphertext = Nothing
        _ciphertext = New MemoryStream
    End Sub
End Class


=======================================================
3.Class SXMLComputerCipherKey.vb
----------------------------------------------------------------
Imports System
Imports System.Security.Cryptography
Imports System.IO

Public Class SXMLComputerCipherKey
    Implements ISXMLCipherKey

    Private _ComputerDrive As String
    Private _cipherKey As Byte()

    Public Sub New(ByVal harddriveletter As String)
        _ComputerDrive = harddriveletter
    End Sub

    Public Sub CipherKeyFinalize() Implements ISXMLCipherKey.CipherKeyFinalize
        Dim _md5 As New MD5CryptoServiceProvider
        Dim encoder As New Text.ASCIIEncoding
        Dim _tmpStr As String

        Throw New NotSupportedException("SXMLComputerCipherKey::CipherKeyFinalize() has not yet been implmented and/or completed!")
    End Sub

    Public ReadOnly Property CipherKey() As Byte() Implements ISXMLCipherKey.CipherKey
        Get
            Return _cipherKey
        End Get
    End Property
End Class

=======================================================
4.Class SXMLCipherKey.vb
----------------------------------------------------------------
Imports System
Imports System.IO
Imports System.Security.Cryptography

Public Class SXMLCipherKey
    Implements ISXMLCipherKey

    Private _keydata As String
    Private _cipherkey As Byte()

    Public Sub New(ByVal pass As String)
        _keydata = pass
    End Sub

    Public Sub CipherKeyFinalize() Implements ISXMLCipherKey.CipherKeyFinalize
        Dim encoder As New Text.ASCIIEncoding
        Dim _tmpbytes As Byte()
        Dim _md5 As New MD5CryptoServiceProvider

        _tmpbytes = encoder.GetBytes(_keydata)
        _cipherkey = _md5.ComputeHash(_tmpbytes)
    End Sub

    Public ReadOnly Property CipherKey() As Byte() Implements ISXMLCipherKey.CipherKey
        Get
            Return _cipherkey
        End Get
    End Property


End Class

=======================================================
Form1
Imports System.IO.Path

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents Button2 As System.Windows.Forms.Button
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents Button3 As System.Windows.Forms.Button
    Friend WithEvents btnExit As System.Windows.Forms.Button
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.TextBox1 = New System.Windows.Forms.TextBox
        Me.Button1 = New System.Windows.Forms.Button
        Me.Button2 = New System.Windows.Forms.Button
        Me.Label1 = New System.Windows.Forms.Label
        Me.Button3 = New System.Windows.Forms.Button
        Me.btnExit = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'TextBox1
        '
        Me.TextBox1.Location = New System.Drawing.Point(4, 23)
        Me.TextBox1.Name = "TextBox1"
        Me.TextBox1.Size = New System.Drawing.Size(264, 20)
        Me.TextBox1.TabIndex = 0
        Me.TextBox1.Text = ""
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(8, 56)
        Me.Button1.Name = "Button1"
        Me.Button1.TabIndex = 1
        Me.Button1.Text = "Encrypt"
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(100, 56)
        Me.Button2.Name = "Button2"
        Me.Button2.TabIndex = 2
        Me.Button2.Text = "Decrypt"
        '
        'Label1
        '
        Me.Label1.Location = New System.Drawing.Point(20, -1)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(248, 23)
        Me.Label1.TabIndex = 3
        Me.Label1.Text = "Enter XML file to encrypt"
        Me.Label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        '
        'Button3
        '
        Me.Button3.Location = New System.Drawing.Point(270, 24)
        Me.Button3.Name = "Button3"
        Me.Button3.Size = New System.Drawing.Size(28, 23)
        Me.Button3.TabIndex = 4
        Me.Button3.Text = "..."
        '
        'btnExit
        '
        Me.btnExit.Location = New System.Drawing.Point(196, 56)
        Me.btnExit.Name = "btnExit"
        Me.btnExit.TabIndex = 8
        Me.btnExit.Text = "Exit"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(308, 86)
        Me.Controls.Add(Me.btnExit)
        Me.Controls.Add(Me.Button3)
        Me.Controls.Add(Me.Label1)
        Me.Controls.Add(Me.Button2)
        Me.Controls.Add(Me.Button1)
        Me.Controls.Add(Me.TextBox1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Dim files(2) As String
    Dim mykey As New SXMLCipherKey("Iouri")
    Dim encstrm As IO.FileStream
    Dim sxml As New SecureXML(mykey)

    Dim sFile As String

    'encrypt
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        files(0) = TextBox1.Text
        files(1) = TextBox1.Text.Substring(0, TextBox1.Text.Length - sFile.Length) & "Encrypted.xml"
        Me.EncryptXML()
        MessageBox.Show("XML file is encrypted")
    End Sub

    'decrypt
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        files(1) = TextBox1.Text.Substring(0, TextBox1.Text.Length - sFile.Length) & "Encrypted.xml"
        files(2) = TextBox1.Text.Substring(0, TextBox1.Text.Length - sFile.Length) & "Decrypted.xml"
        Me.DecryptXML()
        MessageBox.Show("XML file is decrypted")
    End Sub
    Private Sub EncryptXML()
        Dim xmldoc As New Xml.XmlDocument

        'crate Encrypted xml
        encstrm = New IO.FileStream(files(1), IO.FileMode.OpenOrCreate)

        xmldoc.Load(files(0))

        sxml.Save(xmldoc, encstrm)
        encstrm.Flush()
        encstrm.Close()

    End Sub
    Private Sub DecryptXML()
        'create decrypted xml
        encstrm = New IO.FileStream(files(1), IO.FileMode.OpenOrCreate)
        encstrm.Seek(0, IO.SeekOrigin.Begin)

        sxml.Reset()
        Dim newxml As Xml.XmlDocument
        newxml = sxml.Load(encstrm)

        newxml.Save(files(2))
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Dim od As New OpenFileDialog
        With od
            .InitialDirectory = "..\XMLFiles\"
            .Filter = "XML Files (*)|;*.xml"
            If .ShowDialog() = DialogResult.OK Then
                TextBox1.Text = GetFullPath(.FileName) 'see import on the top
                sFile = GetFileName(.FileName)
            End If
        End With

        If TextBox1.Text.Length = 0 Then
            MessageBox.Show("Enter XML file")
            Exit Sub
        End If

    End Sub

    Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
        Me.Close()
    End Sub

End Class
0
 
LVL 2

Author Comment

by:UberDeveloper
Comment Utility
-=iboutchkine=-

Awsome code when when I try and Decrypt the file I get this error:

'create decrypted xml
        encstrm = New IO.FileStream(files(1), IO.FileMode.OpenOrCreate)
        encstrm.Seek(0, IO.SeekOrigin.Begin)

        sxml.Reset()
        Dim newxml As Xml.XmlDocument
        newxml = sxml.Load(encstrm)

        newxml.Save(files(2)) <<<<----------------------------------Object reference not set to an instance of an object

Steps to reproduce:
1.  I have a file i'm using called Default.XML when I select that file and click the Encrypt button everything works fine.
2.  Another file is added to the folder called Encrypted.XML
3. When I select the "encrypted.xml file and then click the Decrypt button I get the above error.

Notes:
The Default.XML file is in a folder by itself.
One time when i ran this there was a 3rd file created called EnEncrypted.XML but the size was 0 bytes.  I have not been able to reproduce this.
0
 
LVL 2

Author Comment

by:UberDeveloper
Comment Utility
I stepped through the code and it looks like when it gets here:

Private Function ReadHeader(ByRef header As SXMLDataHeader, ByVal input As BinaryReader) As Boolean
       Dim hdr As New SXMLDataHeader

       hdr.token = input.ReadInt32()

       If hdr.token <> SXML_DATAHEADER_TOKEN Then
           Return False
       End If

       hdr.Length = input.ReadInt32()

       If hdr.Length <= 0 Or hdr.Length > (input.BaseStream.Length) Then <<<<<-----------The hdr length is 0 so FALSE  is returned
           Return False
       End If

       header = hdr
       Return True


0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 28

Expert Comment

by:iboutchkine
Comment Utility
I have folder XMLFiles at the same level as bin folder
I was following your steps and could not reproduce an error.

I have encripted file and then try to decrypt several times. Everything is working fine

If you want I can send you a zip of the whole solution

Try with different XML files. Maybe this is the problem??????
0
 
LVL 2

Author Comment

by:UberDeveloper
Comment Utility
Ok I just got it to work.  I didn't want to just cut and paste your code because then you don't ever learn anything.  So I actually typed it all out and I had this:


header.length = input.ReadInt32()

Instead of:

hdr.length = input.ReadInt32()


Thank you very much for all your help.


0
 
LVL 28

Expert Comment

by:iboutchkine
Comment Utility
You are welcome
0
 

Expert Comment

by:scorpion53061
Comment Utility
Ibou,

Is it against the rules for you to send me a zip of this solution?
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now