Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. File (XmlDocument) Encryption / Decryption improvements

File (XmlDocument) Encryption / Decryption improvements

Scheduled Pinned Locked Moved C#
questionalgorithmsdata-structuressecurityxml
19 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Ennis Ray Lynch Jr

    Isn't that user specific?

    Need a C# Consultant? I'm available.
    Happiness in intelligent people is the rarest thing I know. -- Ernest Hemingway

    S Offline
    S Offline
    Skippums
    wrote on last edited by
    #10

    Yes, it is user specific... I suggested this because a previous post suggested that the user's password should be used as the key, which would also make it user specific.

    -Jeff

    D 1 Reply Last reply
    0
    • S Skippums

      Yes, it is user specific... I suggested this because a previous post suggested that the user's password should be used as the key, which would also make it user specific.

      -Jeff

      D Offline
      D Offline
      DaveyM69
      wrote on last edited by
      #11

      There will be many users accessing this so this isn't viable unfortunately. Thanks for the suggestion though.

      1 Reply Last reply
      0
      • E ekynox

        G'day, A little while back I ran into a similar problem of storing data in a XML file which needs to be encrypted/decrypted as required. I found that using the Cryptography Application Block from Enterprise Library very useful. Purely because I could generate the symmetric key file specific to the user's credential's or machine config. Also you need to consider what happens to the encrypted/decrypted data memory once you have finished with it as well. I can post some code if you are unfamiliar with the Cryptography Application Block. To lock a file during Read/Write there is a class within .net that allows you do it. It escapes my mind right now. cheers, V

        D Offline
        D Offline
        DaveyM69
        wrote on last edited by
        #12

        Downloaded the Enterprise Library - I'll definately look at it in detail. For now, the CryptoStream will suffice. Thanks.

        1 Reply Last reply
        0
        • E Ennis Ray Lynch Jr

          Use the CryptoStream library class. If you want the data to be really secure use the Users password to encrypt the data that way programmers can't even get to it.

          Need a C# Consultant? I'm available.
          Happiness in intelligent people is the rarest thing I know. -- Ernest Hemingway

          D Offline
          D Offline
          DaveyM69
          wrote on last edited by
          #13

          I ended up with this - a slight variation on the examle given in MSDN.

          class CryptoStreamEncryption
          {
          private static byte[] Key = ASCIIEncoding.ASCII.GetBytes(Constants.Misc.MyKey);
          private static byte[] IV = ASCIIEncoding.ASCII.GetBytes(Constants.Misc.MyKey);

              public static void Encrypt(XmlDocument ThisDocument, string FullPath)
              {
                  try
                  {
                      FileStream fStream = File.Open(FullPath, FileMode.Create);
                      Rijndael RijndaelAlg = Rijndael.Create();
                      CryptoStream cStream = new CryptoStream(fStream, RijndaelAlg.CreateEncryptor(Key, IV), CryptoStreamMode.Write);
                      StreamWriter sWriter = new StreamWriter(cStream);
                      try
                      {
                          sWriter.WriteLine(ThisDocument.OuterXml);
                      }
                      catch (Exception e)
                      {
                          Console.WriteLine("An error occurred: {0}", e.Message);
                      }
                      finally
                      {
                          sWriter.Close();
                          cStream.Close();
                          fStream.Close();
                      }
                  }
                  catch (CryptographicException e)
                  {
                      Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
                  }
                  catch (UnauthorizedAccessException e)
                  {
                      Console.WriteLine("A file error occurred: {0}", e.Message);
                  }
          
              }
          
              public static XmlDocument Decrypt(string FullPath)
              {
                  XmlDocument ThisDocument = new XmlDocument();
                  string val = null;
                  try
                  {
                      FileStream fStream = File.Open(FullPath, FileMode.Open);
                      Rijndael RijndaelAlg = Rijndael.Create();
                      CryptoStream cStream = new CryptoStream(fStream, RijndaelAlg.CreateDecryptor(Key, IV), CryptoStreamMode.Read);
                      StreamReader sReader = new StreamReader(cStream);
                      try
                      {
                          val = sReader.ReadLine();
                      }
                      catch (Exception e)
                      {
                          Console.WriteLine("An error occurred: {0}", e.Message);
                      }
                      finally
                      {
                          sReader.Close();
                          cStream.Close();
                          fStream.Close();
                      }
                  }
                  catch (CryptographicExcep
          
          S 1 Reply Last reply
          0
          • D DaveyM69

            I ended up with this - a slight variation on the examle given in MSDN.

            class CryptoStreamEncryption
            {
            private static byte[] Key = ASCIIEncoding.ASCII.GetBytes(Constants.Misc.MyKey);
            private static byte[] IV = ASCIIEncoding.ASCII.GetBytes(Constants.Misc.MyKey);

                public static void Encrypt(XmlDocument ThisDocument, string FullPath)
                {
                    try
                    {
                        FileStream fStream = File.Open(FullPath, FileMode.Create);
                        Rijndael RijndaelAlg = Rijndael.Create();
                        CryptoStream cStream = new CryptoStream(fStream, RijndaelAlg.CreateEncryptor(Key, IV), CryptoStreamMode.Write);
                        StreamWriter sWriter = new StreamWriter(cStream);
                        try
                        {
                            sWriter.WriteLine(ThisDocument.OuterXml);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("An error occurred: {0}", e.Message);
                        }
                        finally
                        {
                            sWriter.Close();
                            cStream.Close();
                            fStream.Close();
                        }
                    }
                    catch (CryptographicException e)
                    {
                        Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
                    }
                    catch (UnauthorizedAccessException e)
                    {
                        Console.WriteLine("A file error occurred: {0}", e.Message);
                    }
            
                }
            
                public static XmlDocument Decrypt(string FullPath)
                {
                    XmlDocument ThisDocument = new XmlDocument();
                    string val = null;
                    try
                    {
                        FileStream fStream = File.Open(FullPath, FileMode.Open);
                        Rijndael RijndaelAlg = Rijndael.Create();
                        CryptoStream cStream = new CryptoStream(fStream, RijndaelAlg.CreateDecryptor(Key, IV), CryptoStreamMode.Read);
                        StreamReader sReader = new StreamReader(cStream);
                        try
                        {
                            val = sReader.ReadLine();
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("An error occurred: {0}", e.Message);
                        }
                        finally
                        {
                            sReader.Close();
                            cStream.Close();
                            fStream.Close();
                        }
                    }
                    catch (CryptographicExcep
            
            S Offline
            S Offline
            Skippums
            wrote on last edited by
            #14

            This is close to the other method I was going to suggest, so now I don't have to type it! I will, however, reiterate that key storage is essential to security, and simply including it in the compiled dll is NOT secure. Since it looks like you are doing this, I will reiterate (original warning came from one of the MVP's) that encrypting data does not imply security. You MUST have a way to secure the key from being read by another party for the encryption above to be secure. This is part of the key management strategy, and I encourage you to research it via the web to get ideas.

            -Jeff

            D 1 Reply Last reply
            0
            • S Skippums

              This is close to the other method I was going to suggest, so now I don't have to type it! I will, however, reiterate that key storage is essential to security, and simply including it in the compiled dll is NOT secure. Since it looks like you are doing this, I will reiterate (original warning came from one of the MVP's) that encrypting data does not imply security. You MUST have a way to secure the key from being read by another party for the encryption above to be secure. This is part of the key management strategy, and I encourage you to research it via the web to get ideas.

              -Jeff

              D Offline
              D Offline
              DaveyM69
              wrote on last edited by
              #15

              Hi Jeff, Yeah - I did take your point on board, but getting the encryption/decryption working/performing optimally was my priority at that point. The key storage is a bit of a problem as the encrypted data is stored on a network share with many clients needing access it (the reason for the filelock question) so they all need to know the key! I thought maybe using the assembly's GUID with a little hashing as an extra layer may be a solution but I've been strugglig to get the GUID within code. Any suggestions?

              S 1 Reply Last reply
              0
              • D DaveyM69

                Hi Jeff, Yeah - I did take your point on board, but getting the encryption/decryption working/performing optimally was my priority at that point. The key storage is a bit of a problem as the encrypted data is stored on a network share with many clients needing access it (the reason for the filelock question) so they all need to know the key! I thought maybe using the assembly's GUID with a little hashing as an extra layer may be a solution but I've been strugglig to get the GUID within code. Any suggestions?

                S Offline
                S Offline
                Skippums
                wrote on last edited by
                #16

                OK, this is an entirely incorrect way to go about this. You should NEVER require the users to know the key to encrypt/decrypt data. This leads to software upgrade nightmares, as key management is nearly impossible. What you should do is have a SINGLE web application (or a few for redundancy)that can get and decrypt the data, then return the decrypted data to the client (or re-encrypt it on the fly with a session key, if you want it to be secure). Hard-coding keys into client apps is a bad idea, as one key leak is detrimental to the entire system. On the other hand, with a single web app, changing the key after a known leak is easy, as you have control over both the data and the web app. Just a suggestion, but if you do implement the web app method, you could make it run as a specific user, so again, you could encrypt/decrypt on a user level, which alleviates you from having to manage the crypto key, as explained in earlier posts. Hope this helps,

                -Jeff

                D 1 Reply Last reply
                0
                • S Skippums

                  OK, this is an entirely incorrect way to go about this. You should NEVER require the users to know the key to encrypt/decrypt data. This leads to software upgrade nightmares, as key management is nearly impossible. What you should do is have a SINGLE web application (or a few for redundancy)that can get and decrypt the data, then return the decrypted data to the client (or re-encrypt it on the fly with a session key, if you want it to be secure). Hard-coding keys into client apps is a bad idea, as one key leak is detrimental to the entire system. On the other hand, with a single web app, changing the key after a known leak is easy, as you have control over both the data and the web app. Just a suggestion, but if you do implement the web app method, you could make it run as a specific user, so again, you could encrypt/decrypt on a user level, which alleviates you from having to manage the crypto key, as explained in earlier posts. Hope this helps,

                  -Jeff

                  D Offline
                  D Offline
                  DaveyM69
                  wrote on last edited by
                  #17

                  The users do not need to know the key - only the application instances. They may only have network access and not internet so a web app is not an option so I think I'm stuck with hard coding it in some way but hopefully well obscured within the app.

                  S 1 Reply Last reply
                  0
                  • D DaveyM69

                    The users do not need to know the key - only the application instances. They may only have network access and not internet so a web app is not an option so I think I'm stuck with hard coding it in some way but hopefully well obscured within the app.

                    S Offline
                    S Offline
                    Skippums
                    wrote on last edited by
                    #18

                    I don't think you need to be "online" to connect to a web service. If you use a local computer, the address gets resolved within your own network (I think, but you could test this by disconnecting from the internet and seeing if you can still access other computers on your network). Again, I will reiterate that giving multiple users knowledge of the key makes the key more accessible and therefore, less secure. Anyway, to get the GUID of the assembly you can just do the following:

                    using System.Reflection;
                    using System.Runtime.InteropServices;
                    ...
                    object[] res = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), true);
                    string guid = null;
                    if (res.Length > 0)
                    guid = ((GuidAttribute)res[0]).Value;

                    Hope this helps,

                    -Jeff

                    D 1 Reply Last reply
                    0
                    • S Skippums

                      I don't think you need to be "online" to connect to a web service. If you use a local computer, the address gets resolved within your own network (I think, but you could test this by disconnecting from the internet and seeing if you can still access other computers on your network). Again, I will reiterate that giving multiple users knowledge of the key makes the key more accessible and therefore, less secure. Anyway, to get the GUID of the assembly you can just do the following:

                      using System.Reflection;
                      using System.Runtime.InteropServices;
                      ...
                      object[] res = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), true);
                      string guid = null;
                      if (res.Length > 0)
                      guid = ((GuidAttribute)res[0]).Value;

                      Hope this helps,

                      -Jeff

                      D Offline
                      D Offline
                      DaveyM69
                      wrote on last edited by
                      #19

                      That's helped alot Jeff, Many thanks.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups