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. .NET (Core and Framework)
  4. Securing strings in .NET....possibility?

Securing strings in .NET....possibility?

Scheduled Pinned Locked Moved .NET (Core and Framework)
csharpdotnetsecurityperformancehelp
11 Posts 6 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.
  • J Offline
    J Offline
    Jon Rista
    wrote on last edited by
    #1

    I have been trying to come up with a way to manage string security in .NET. The whole idea of a SecureString is nice, but the way it works in .NET right now is atrocious...it just doesn't really provide any value given how it is such a pain to work with. I wrote the following extension to System.String...curious what others think:

    public static class StringExtensions
    {
    const string OVERWRITE_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=~!@#$%^&*()_+";
    const int MAX_OVERWRITES = 3;

    /// <summary>
    /// Performs a secure wipe of the string in memory, overwriting the 
    /// existing contents with junk, then again with nil.
    /// </summary>
    /// <param name="str">The string to wipe.</param>
    public static unsafe void SecureWipe(this String str)
    {
    	// If string is null, there is no securing to be done...return gracefully
    	if (str == null)
    		return;
    
    	// Prepare
    	Random rnd = new Random();
    	int maxRnd = OVERWRITE\_CHARS.Length;
    	int maxLen = str.Length;
    
    	// Pin the string in memory so GC doesn't mess with it, and get a pointer
    	fixed (char\* c = str)
    	{
    		// Overwrite with random junk a few times
    		for (int r = 0; r < MAX\_OVERWRITES; r++)
    		{
    			for (int i = 0; i < maxLen; i++)
    			{
    				char rndChar = OVERWRITE\_CHARS\[rnd.Next(maxRnd)\];
    				c\[i\] = rndChar;
    			}
    		}
    
    		// Overwrite one last time with nil
    		for (int i=0; i < maxlen; i++)
                        {
    			c\[i\] = '\\0';
    		}
    
    		// Set the length to zero
    		int\* len = (int\*)c;
    		len\[-1\] = 0;
    	}
    }
    

    }

    I know its possible for the .NET framework to create copies of a string in internal framework methods...nothing I can do about that, and when you need to display a string, SecureString doesn't solve that problem either. But at least with something like this...you can wipe the copy that hackers are most likely to get. Thoughts? Improvements? Reasons why it won't work?

    W D P S 4 Replies Last reply
    0
    • J Jon Rista

      I have been trying to come up with a way to manage string security in .NET. The whole idea of a SecureString is nice, but the way it works in .NET right now is atrocious...it just doesn't really provide any value given how it is such a pain to work with. I wrote the following extension to System.String...curious what others think:

      public static class StringExtensions
      {
      const string OVERWRITE_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=~!@#$%^&*()_+";
      const int MAX_OVERWRITES = 3;

      /// <summary>
      /// Performs a secure wipe of the string in memory, overwriting the 
      /// existing contents with junk, then again with nil.
      /// </summary>
      /// <param name="str">The string to wipe.</param>
      public static unsafe void SecureWipe(this String str)
      {
      	// If string is null, there is no securing to be done...return gracefully
      	if (str == null)
      		return;
      
      	// Prepare
      	Random rnd = new Random();
      	int maxRnd = OVERWRITE\_CHARS.Length;
      	int maxLen = str.Length;
      
      	// Pin the string in memory so GC doesn't mess with it, and get a pointer
      	fixed (char\* c = str)
      	{
      		// Overwrite with random junk a few times
      		for (int r = 0; r < MAX\_OVERWRITES; r++)
      		{
      			for (int i = 0; i < maxLen; i++)
      			{
      				char rndChar = OVERWRITE\_CHARS\[rnd.Next(maxRnd)\];
      				c\[i\] = rndChar;
      			}
      		}
      
      		// Overwrite one last time with nil
      		for (int i=0; i < maxlen; i++)
                          {
      			c\[i\] = '\\0';
      		}
      
      		// Set the length to zero
      		int\* len = (int\*)c;
      		len\[-1\] = 0;
      	}
      }
      

      }

      I know its possible for the .NET framework to create copies of a string in internal framework methods...nothing I can do about that, and when you need to display a string, SecureString doesn't solve that problem either. But at least with something like this...you can wipe the copy that hackers are most likely to get. Thoughts? Improvements? Reasons why it won't work?

      W Offline
      W Offline
      Wendelius
      wrote on last edited by
      #2

      I'm not able to say if there are scenarios when this wouldn't work (concerning internal memory handling), but as far as I can see, looks very good. Now you've chosen to do this as an extension, which is good since it can be used for any string. However, would there be a point if you also create a wrapper class for this kind of strings. With the wrapper you could possibly have more control over the string usage and behaviour. For example you could have separate mechanisms to show the string or to modify the string etc.

      The need to optimize rises from a bad design.My articles[^]

      J 1 Reply Last reply
      0
      • J Jon Rista

        I have been trying to come up with a way to manage string security in .NET. The whole idea of a SecureString is nice, but the way it works in .NET right now is atrocious...it just doesn't really provide any value given how it is such a pain to work with. I wrote the following extension to System.String...curious what others think:

        public static class StringExtensions
        {
        const string OVERWRITE_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=~!@#$%^&*()_+";
        const int MAX_OVERWRITES = 3;

        /// <summary>
        /// Performs a secure wipe of the string in memory, overwriting the 
        /// existing contents with junk, then again with nil.
        /// </summary>
        /// <param name="str">The string to wipe.</param>
        public static unsafe void SecureWipe(this String str)
        {
        	// If string is null, there is no securing to be done...return gracefully
        	if (str == null)
        		return;
        
        	// Prepare
        	Random rnd = new Random();
        	int maxRnd = OVERWRITE\_CHARS.Length;
        	int maxLen = str.Length;
        
        	// Pin the string in memory so GC doesn't mess with it, and get a pointer
        	fixed (char\* c = str)
        	{
        		// Overwrite with random junk a few times
        		for (int r = 0; r < MAX\_OVERWRITES; r++)
        		{
        			for (int i = 0; i < maxLen; i++)
        			{
        				char rndChar = OVERWRITE\_CHARS\[rnd.Next(maxRnd)\];
        				c\[i\] = rndChar;
        			}
        		}
        
        		// Overwrite one last time with nil
        		for (int i=0; i < maxlen; i++)
                            {
        			c\[i\] = '\\0';
        		}
        
        		// Set the length to zero
        		int\* len = (int\*)c;
        		len\[-1\] = 0;
        	}
        }
        

        }

        I know its possible for the .NET framework to create copies of a string in internal framework methods...nothing I can do about that, and when you need to display a string, SecureString doesn't solve that problem either. But at least with something like this...you can wipe the copy that hackers are most likely to get. Thoughts? Improvements? Reasons why it won't work?

        D Offline
        D Offline
        Dave Kreskowiak
        wrote on last edited by
        #3

        I think this would be a bit of a nightmare to manage since string operations usually end up creating more strings. A simple concantenation leaves to the initial strings intact and creates a third. Instead of a string automatically wiping itself at the end of its life, you have to manage that for each and every instance of a secured string.

        A guide to posting questions on CodeProject[^]
        Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
             2006, 2007, 2008

        J 1 Reply Last reply
        0
        • J Jon Rista

          I have been trying to come up with a way to manage string security in .NET. The whole idea of a SecureString is nice, but the way it works in .NET right now is atrocious...it just doesn't really provide any value given how it is such a pain to work with. I wrote the following extension to System.String...curious what others think:

          public static class StringExtensions
          {
          const string OVERWRITE_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=~!@#$%^&*()_+";
          const int MAX_OVERWRITES = 3;

          /// <summary>
          /// Performs a secure wipe of the string in memory, overwriting the 
          /// existing contents with junk, then again with nil.
          /// </summary>
          /// <param name="str">The string to wipe.</param>
          public static unsafe void SecureWipe(this String str)
          {
          	// If string is null, there is no securing to be done...return gracefully
          	if (str == null)
          		return;
          
          	// Prepare
          	Random rnd = new Random();
          	int maxRnd = OVERWRITE\_CHARS.Length;
          	int maxLen = str.Length;
          
          	// Pin the string in memory so GC doesn't mess with it, and get a pointer
          	fixed (char\* c = str)
          	{
          		// Overwrite with random junk a few times
          		for (int r = 0; r < MAX\_OVERWRITES; r++)
          		{
          			for (int i = 0; i < maxLen; i++)
          			{
          				char rndChar = OVERWRITE\_CHARS\[rnd.Next(maxRnd)\];
          				c\[i\] = rndChar;
          			}
          		}
          
          		// Overwrite one last time with nil
          		for (int i=0; i < maxlen; i++)
                              {
          			c\[i\] = '\\0';
          		}
          
          		// Set the length to zero
          		int\* len = (int\*)c;
          		len\[-1\] = 0;
          	}
          }
          

          }

          I know its possible for the .NET framework to create copies of a string in internal framework methods...nothing I can do about that, and when you need to display a string, SecureString doesn't solve that problem either. But at least with something like this...you can wipe the copy that hackers are most likely to get. Thoughts? Improvements? Reasons why it won't work?

          P Offline
          P Offline
          PIEBALDconsult
          wrote on last edited by
          #4

          Yeah, what they said. Plus I would make the Random a static member of the class rather than creating a new one on each call. I might also use a cryptographic randomizer instead of Random. However, I expect you may be tryingto fix a non-existant problem.

          Jon Rista wrote:

          the way it works in .NET right now is atrocious

          Please explain.

          J 1 Reply Last reply
          0
          • J Jon Rista

            I have been trying to come up with a way to manage string security in .NET. The whole idea of a SecureString is nice, but the way it works in .NET right now is atrocious...it just doesn't really provide any value given how it is such a pain to work with. I wrote the following extension to System.String...curious what others think:

            public static class StringExtensions
            {
            const string OVERWRITE_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=~!@#$%^&*()_+";
            const int MAX_OVERWRITES = 3;

            /// <summary>
            /// Performs a secure wipe of the string in memory, overwriting the 
            /// existing contents with junk, then again with nil.
            /// </summary>
            /// <param name="str">The string to wipe.</param>
            public static unsafe void SecureWipe(this String str)
            {
            	// If string is null, there is no securing to be done...return gracefully
            	if (str == null)
            		return;
            
            	// Prepare
            	Random rnd = new Random();
            	int maxRnd = OVERWRITE\_CHARS.Length;
            	int maxLen = str.Length;
            
            	// Pin the string in memory so GC doesn't mess with it, and get a pointer
            	fixed (char\* c = str)
            	{
            		// Overwrite with random junk a few times
            		for (int r = 0; r < MAX\_OVERWRITES; r++)
            		{
            			for (int i = 0; i < maxLen; i++)
            			{
            				char rndChar = OVERWRITE\_CHARS\[rnd.Next(maxRnd)\];
            				c\[i\] = rndChar;
            			}
            		}
            
            		// Overwrite one last time with nil
            		for (int i=0; i < maxlen; i++)
                                {
            			c\[i\] = '\\0';
            		}
            
            		// Set the length to zero
            		int\* len = (int\*)c;
            		len\[-1\] = 0;
            	}
            }
            

            }

            I know its possible for the .NET framework to create copies of a string in internal framework methods...nothing I can do about that, and when you need to display a string, SecureString doesn't solve that problem either. But at least with something like this...you can wipe the copy that hackers are most likely to get. Thoughts? Improvements? Reasons why it won't work?

            S Offline
            S Offline
            ssclaire
            wrote on last edited by
            #5

            I'm still trying to figure out what security scenario you are trying to protect from. Some sort of forensic analysis of memory (like wiping a hard drive)? Sorry if I misunderstand. But the whole concept is fraught with problems. As you said, .NET and Windows is free to move and copy memory at will. Virtually any string operation will make a copy of the original string(s). What about, paging to disk? That would seem to be much more of a vulnerability. Also, what about interning? Someone correct me if I am wrong but, doing something like this:

            string firstString = "abc";
            string secondString = "abc";
            SecureWipe(FirstString);

            ...could potentially destroy the contents of secondString (because of the unsafe code pointing to the intern'ed string). Besides, as Dave said (above), if you did something like this:

            string firstString = "abc";
            string secondString = "xyz";
            secureWipe(firstString);
            secureWipe(secondString);

            firstString and secondString would likely be overwritten with the same "random" character sequence. That's not "secure". Move the instance of Random() outside of SecureWipe() so it is only executed once.

            J 1 Reply Last reply
            0
            • S ssclaire

              I'm still trying to figure out what security scenario you are trying to protect from. Some sort of forensic analysis of memory (like wiping a hard drive)? Sorry if I misunderstand. But the whole concept is fraught with problems. As you said, .NET and Windows is free to move and copy memory at will. Virtually any string operation will make a copy of the original string(s). What about, paging to disk? That would seem to be much more of a vulnerability. Also, what about interning? Someone correct me if I am wrong but, doing something like this:

              string firstString = "abc";
              string secondString = "abc";
              SecureWipe(FirstString);

              ...could potentially destroy the contents of secondString (because of the unsafe code pointing to the intern'ed string). Besides, as Dave said (above), if you did something like this:

              string firstString = "abc";
              string secondString = "xyz";
              secureWipe(firstString);
              secureWipe(secondString);

              firstString and secondString would likely be overwritten with the same "random" character sequence. That's not "secure". Move the instance of Random() outside of SecureWipe() so it is only executed once.

              J Offline
              J Offline
              Jon Rista
              wrote on last edited by
              #6

              First off, this is really more of a proof of concept than a final roduct. More extensions, or perhapse a new SecureString class, could be created to handle copy, concat, modify, etc. The basic goal is to scramble strings when your done with them so that leftover strings in memory don't contain any sensitive data, and maybe encrypt the string until it needs to be read. It tries to solve the same general problem that the SecureString class in the .NET framework does. It is possible to pin data in memory with .NET, so preventing it from being moved around by the GC is possible. I'm sure it is also possible to make it part of the non-paged pool of memory for the app, so it will never be swapped to disk. Pulling the Random out is easy to do, too...however even if all strings were scrambled with the same random data, that wouldn't matter...the original data is still gone (overwriting with random is probably moot, since its overwritten with nils and the length shrunk to 0 after, anyway...there isn't any kind of magnetic residue like there is with a hard drive, so I will probably take the random overwrites out and just use \0). The biggest problem that you mentioned, I think, is the interned strings problem. I am not sure there is a solution to that.

              1 Reply Last reply
              0
              • P PIEBALDconsult

                Yeah, what they said. Plus I would make the Random a static member of the class rather than creating a new one on each call. I might also use a cryptographic randomizer instead of Random. However, I expect you may be tryingto fix a non-existant problem.

                Jon Rista wrote:

                the way it works in .NET right now is atrocious

                Please explain.

                J Offline
                J Offline
                Jon Rista
                wrote on last edited by
                #7

                Its atricuous because once the data is in a SecureSring, there is no real way to use it outside of unmanaged code and BSTR...and I try hard to avoid unmanaged code in my projects. It is entirely possible I am trying to solve a non-existent problem. I was just experimenting. ;P

                S 1 Reply Last reply
                0
                • D Dave Kreskowiak

                  I think this would be a bit of a nightmare to manage since string operations usually end up creating more strings. A simple concantenation leaves to the initial strings intact and creates a third. Instead of a string automatically wiping itself at the end of its life, you have to manage that for each and every instance of a secured string.

                  A guide to posting questions on CodeProject[^]
                  Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
                       2006, 2007, 2008

                  J Offline
                  J Offline
                  Jon Rista
                  wrote on last edited by
                  #8

                  It is easy enough to add more extensions, such as SecureCopy, SecureCat, SecureModify, etc. that automatically wipe the old versions after the new is created. It might be better to have a whole SecureString class for it rather than extensions, though.

                  1 Reply Last reply
                  0
                  • W Wendelius

                    I'm not able to say if there are scenarios when this wouldn't work (concerning internal memory handling), but as far as I can see, looks very good. Now you've chosen to do this as an extension, which is good since it can be used for any string. However, would there be a point if you also create a wrapper class for this kind of strings. With the wrapper you could possibly have more control over the string usage and behaviour. For example you could have separate mechanisms to show the string or to modify the string etc.

                    The need to optimize rises from a bad design.My articles[^]

                    J Offline
                    J Offline
                    Jon Rista
                    wrote on last edited by
                    #9

                    Indeed, to make it truely viable it would probably need to be a wrapper class, or perhapse have both the SecureWipe extension and a SecureString that handles copy, concat, etc.

                    1 Reply Last reply
                    0
                    • J Jon Rista

                      Its atricuous because once the data is in a SecureSring, there is no real way to use it outside of unmanaged code and BSTR...and I try hard to avoid unmanaged code in my projects. It is entirely possible I am trying to solve a non-existent problem. I was just experimenting. ;P

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

                      Its atricuous because once the data is in a SecureSring, there is no real way to use it outside of unmanaged code and BSTR...and I try hard to avoid unmanaged code in my projects. The string object is supposed to be immutable; using funny tricks to alter existing string objects is bad mojo since there's generally no way of guaranteeing what references may exist to any particular string. For example, a display routine might decide to keep a cache of strings that have been displayed and their associated bitmaps. Thus, I call the routine to display the word "FOO" and it keeps a reference to the string along with a copy of its bitmap implementation. If the string is later altered to say "BAR", and the routine is later called to display the word "BAR", it may notice that it has "BAR" in its cache and display the cached bitmap (which happens to look like the word "FOO"). If there were more class methods and properties that could operate with StringBuilder objects, then those could be the basis for a semi-secure-string type. Unfortunately, very few classes can accept a StringBuilder directly; nearly all would require first converting it to a normal String, which would in turn throw security out the window.

                      J 1 Reply Last reply
                      0
                      • S supercat9

                        Its atricuous because once the data is in a SecureSring, there is no real way to use it outside of unmanaged code and BSTR...and I try hard to avoid unmanaged code in my projects. The string object is supposed to be immutable; using funny tricks to alter existing string objects is bad mojo since there's generally no way of guaranteeing what references may exist to any particular string. For example, a display routine might decide to keep a cache of strings that have been displayed and their associated bitmaps. Thus, I call the routine to display the word "FOO" and it keeps a reference to the string along with a copy of its bitmap implementation. If the string is later altered to say "BAR", and the routine is later called to display the word "BAR", it may notice that it has "BAR" in its cache and display the cached bitmap (which happens to look like the word "FOO"). If there were more class methods and properties that could operate with StringBuilder objects, then those could be the basis for a semi-secure-string type. Unfortunately, very few classes can accept a StringBuilder directly; nearly all would require first converting it to a normal String, which would in turn throw security out the window.

                        J Offline
                        J Offline
                        Jon Rista
                        wrote on last edited by
                        #11

                        supercat9 wrote:

                        nearly all would require first converting it to a normal String, which would in turn throw security out the window.

                        Correct, which is why I was messing with the idea of wiping the string itself. I basically decided the idea was pointless once someone mentioned interned strings. If a string is interned, there is no real way to know how many references it has, and since an interned string will live for the duration of an applications execution, you'll definitely end up with problems.

                        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