<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>C# Hacker - The Rambling Coder &#187; CodeProject</title>
	<atom:link href="http://www.csharphacker.com/technicalblog/index.php/category/codeproject/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.csharphacker.com/technicalblog</link>
	<description>Thoughts and ponderings on the technical world</description>
	<lastBuildDate>Thu, 22 Jul 2010 02:15:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Who knows of the .Net Secure Strings?</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2010/01/21/who-knows-of-the-net-secure-strings/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2010/01/21/who-knows-of-the-net-secure-strings/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 14:58:29 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=465</guid>
		<description><![CDATA[While SecureString is certainly not a new kid on the block it is often overlooked by .Net programmers that are programming applications that deal with sensitive data (think PCI, KeyManagement, Passwords, Credit cards etc). This article aims to bring everyone up to speed why there is information leakage in .Net and how SecureString aims to resolve that.]]></description>
			<content:encoded><![CDATA[<p>[Warning this is not new stuff - but shouldn't be overlooked if you need to secure sensitive data in your application]</p>
<p>Isn&#8217;t &#8220;Secure String&#8221; an oxymoron for .Net? So if we are thinking about securing some sensitive data in say C or C++ its relatively simple load it into a char array memory and encrypt it, wiping the memory out after the information has been loaded.</p>
<p>Now try that with .Net! From the Microsoft site:</p>
<blockquote><p>&#8220;<a href="http://msdn.microsoft.com/en-us/library/system.string%28VS.71%29.aspx">A String is called immutable because its value cannot be modified once it has been created.</a>&#8220;</p></blockquote>
<p>So how can you destroy one? Set it to empty? Well simply put you can&#8217;t <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Once your string is not longer referenced, or worse yet your object containing the string its time for the <a href="http://msdn.microsoft.com/en-us/library/ms973837.aspx">Garbage Collector</a> to come and do its work. The problem is if your object has been around long enough to get into Generation 1 or 2 then it is going to take a bit longer.</p>
<p>Hmmm so in translation if you keep a password, Credit Card, encryption key or some other sensitive text in memory as a string you cant destroy it (think memset for us oldies!). Only the GC can free the memory for you, and you are dependent on HOW it frees that memory. I personally don&#8217;t know for a fact if it memsets it to blank, or just dereferences the pointer. However I would be willing to bet it is the option that requires the least amount of work and that doesn&#8217;t bode well for controlling the exposure of our sensitive data.</p>
<p>Plainly that proverbially sucks!</p>
<p>Enter the &#8220;<a href="http://msdn.microsoft.com/en-us/library/system.security.securestring.aspx">SecureString</a>&#8221; class, from the MS site it says:</p>
<blockquote><p>&#8220;Represents text that should be kept confidential. The text is encrypted for privacy when being used, and deleted from computer memory when no longer needed.&#8221;</p></blockquote>
<p>Wow doesn&#8217;t that just sound like the ticket we need! Secure, Encryption, delete from memory &#8211; how fantastic! Uh oh keep reading the remarks:</p>
<blockquote><p>&#8220;Your application can render the instance immutable and prevent further modification by invoking the <a href="http://msdn.microsoft.com/en-us/library/system.security.securestring.makereadonly.aspx">MakeReadOnly</a> method.</p>
<p>&#8230;</p>
<p>Use appropriate members of the <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx">System.Runtime.InteropServices..::.Marshal</a> class, such as the <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.securestringtobstr.aspx">SecureStringToBSTR</a> method, to manipulate the value of a SecureString object.&#8221;</p></blockquote>
<p>BSTR &#8211; oh I feel the COM headache coming back!</p>
<p>Actually its really not that bad, but its definitely not a straight swap for a System.String. See some example code below:</p>
<pre class="brush: csharp;">

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security;

namespace CSharpHacker.Utilities
{
   /// &lt;summary&gt;
   /// Demo helper class for &lt;see cref=&quot;SecureString&quot;/&gt;
   /// &lt;/summary&gt;
   public class SensitiveDataHelper
   {
      private SecureString sensitiveData;

      /// &lt;summary&gt;
      /// Gets or sets the sensitive data class from helper
      /// &lt;/summary&gt;
      /// &lt;value&gt;The sensitive data container.&lt;/value&gt;
      public SecureString SensitiveData
      {
         get { return sensitiveData; }
         set { sensitiveData = value; }
      }

      /// &lt;summary&gt;
      /// UNSECURE: Converts the secured sensitive data into an unsecured string.
      /// &lt;/summary&gt;
      /// &lt;remarks&gt;
      /// This is a dangerous function that converts secured information into
      /// unsecured data.
      /// &lt;/remarks&gt;
      /// &lt;returns&gt;String representing the secured data&lt;/returns&gt;
      public string SensitiveDataToString()
      {
         IntPtr ptr = Marshal.SecureStringToGlobalAllocUnicode(this.sensitiveData);
         try
         {
             // Unsecure managed string
             return Marshal.PtrToStringUni(ptr);
         }
         finally
         {
             Marshal.ZeroFreeGlobalAllocUnicode(ptr);
         }
      }

      /// &lt;summary&gt;
      /// UNSECURE: Base64s encodes a SHA512 has of the sensitive data
      /// &lt;/summary&gt;
      /// &lt;returns&gt;SHA512 hash value&lt;/returns&gt;
      public string Base64SensitiveDataHash()
      {
         IntPtr bstr = Marshal.SecureStringToBSTR(sensitiveData);
         try
         {
            // Pretend simple hash function that returns a string - this is fake just for readability!!
            string output = Marshal.PtrToStringBSTR(bstr);

            Marshal.FreeBSTR(bstr);

            SHA512 sha = new SHA512Managed();
            byte[] result = sha.ComputeHash(Encoding.UTF8.GetBytes(output));
            return Convert.ToBase64String(result);
         }
         finally
         {
            Marshal.ZeroFreeBSTR(bstr);
         }
      }

      /// &lt;summary&gt;
      /// Loads the sensitive data into a &lt;see cref=&quot;SecureString&quot;/&gt;
      /// &lt;/summary&gt;
      /// &lt;param name=&quot;sensitiveInformation&quot;&gt;The sensitive information to protect.&lt;/param&gt;
      public void LoadSensitiveData(char[] sensitiveInformation)
      {
         try
         {
            using (SecureString securePassword = new SecureString())
            {
               foreach (char c in sensitiveInformation)
               {
                  securePassword.AppendChar(c);
               }
               securePassword.MakeReadOnly();
               this.sensitiveData = securePassword.Copy();
            }
         }
         finally
         {
            // discard the char array
            Array.Clear(sensitiveInformation, 0, sensitiveInformation.Length);
         }
      }

      /// &lt;summary&gt;
      /// Loads the sensitive data into a &lt;see cref=&quot;SecureString&quot;/&gt;
      /// &lt;/summary&gt;
      /// &lt;param name=&quot;sensitiveInformation&quot;&gt;The sensitive information to protect.&lt;/param&gt;
      public void LoadSensitiveData(string sensitiveInformation)
      {
         char[] sensitive = new char[sensitiveInformation.Length];
         sensitiveInformation.CopyTo(0, sensitive, 0, sensitive.Length);

         LoadSensitiveData(sensitive);
      }

      /// &lt;summary&gt;
      /// Loads the sensitive data into a &lt;see cref=&quot;SecureString&quot;/&gt;
      /// &lt;/summary&gt;
      /// &lt;param name=&quot;sensitiveInformation&quot;&gt;The sensitive information to protect.&lt;/param&gt;
      public void LoadSensitiveData(StringBuilder sensitiveInformation)
      {
         char[] sensitive = new char[sensitiveInformation.Length];
         sensitiveInformation.CopyTo(0, sensitive, 0, sensitive.Length);

         LoadSensitiveData(sensitive);
      }

      /// &lt;summary&gt;
      /// Creates the secure string from string.
      /// &lt;/summary&gt;
      /// &lt;param name=&quot;unprotectedSensitiveInformation&quot;&gt;The unprotected sensitive information.&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public static SecureString CreateSecureStringFromString(string unprotectedSensitiveInformation)
      {
         char[] unprotectedSensitive = unprotectedSensitiveInformation.ToCharArray();
         SecureString secureInformation = new SecureString();
         try
         {
            foreach (char c in unprotectedSensitive)
            {
               secureInformation.AppendChar(c);
            }
            secureInformation.MakeReadOnly();
            return secureInformation;
         }
         finally
         {
            // discard the char array
            Array.Clear(unprotectedSensitive, 0, unprotectedSensitive.Length);
         }
      }
   }
}
</pre>
<p>A word of caution to the above code:</p>
<ul>
<li>SensitiveDataToString &#8211; is considered insecure as it returns a string of the encrypted data. The same data we are trying to encrypt! However it is a commonly requested function, and so there is the implementation.</li>
<li>Base64SensitiveDataHash &#8211; is considered insecure as it currently uses a temporary string (:-( ), at this time I don&#8217;t have a way to converts a BSTR into a an array without going through a string first. One way would be to process it prior to being made ReadOnly, or alternatively someone can write a comment how to convert a C# BSTR into a byte array!</li>
</ul>
<p>So even with all those disclaimers running a program that takes input will still a &#8216;leak information&#8217; for the System.String. Specifically the tricky area is how do you get them into you program in the first place? Read them from a database, WinForm user input, or a web page? Kinda tricky <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ! If you search the web there are implementations of  secure login controls that build it up character by character, but certainly something to think about.</p>
<p>So how Secure is &#8220;SecureString&#8221;? The answer is &#8220;it depends&#8221;, but reasonably secure and a heck of a lot better than System.String. A while ago there was a big storm about tools that can connect to the process and decrypt your SecureStrings. The best rebuttal to this I&#8217;ve seen can be read about in [<a href="http://blogs.msdn.com/shawnfa/archive/2006/11/01/securestring-redux.aspx">SecureString Redux</a>]. I definitely recommend reading this.</p>
<p>Now I have to say I&#8217;ve been meaning to write this for some time now! Hopefully this helped raise awareness of the string leakage risks in the .Net language and ways to help minimize the string information leak scenario.</p>
<p>Potential enhancements to the helper class would be:</p>
<ul>
<li>Make the Hashing really secure, and allow a &#8220;HashAlgorithm&#8221; to be passed in</li>
<li>Allow external encryption</li>
<li>Allow secure serialization of data (via the encryption)</li>
</ul>
<p>Gareth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2010/01/21/who-knows-of-the-net-secure-strings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How security is very much like MMA</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/09/20/how-security-is-very-much-like-mma/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/09/20/how-security-is-very-much-like-mma/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 16:19:25 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=461</guid>
		<description><![CDATA[It occurred to me after following the most recent UFC MMA (via the web blogs rather than PPV as I&#8217;m still too cheap!) that security and MMA have a lot in common. More precisely the fighters in a stable as very similar to security algorithms or process. Once a fighters weakness has been exposed there [...]]]></description>
			<content:encoded><![CDATA[<p>It occurred to me after following the most recent UFC MMA (via the web blogs rather than PPV as I&#8217;m still too cheap!) that security and MMA have a lot in common. More precisely the fighters in a stable as very similar to security algorithms or process.</p>
<p>Once a fighters weakness has been exposed there is really nothing you can do to unhide that weakness. You could have the best fighter in the world one day, then the weakness is exposed&#8230; You are in trouble!</p>
<p>Security is very much the same. You can perform all the scans, probes, fuzzes, code reviews and feel confident (well as confident anyone does in the security world!) that you are pretty well covered. One revelation a day later can completely invalidate your expectations, and you have to completely start over. Sometimes it is a slow build up, other times it is the equivalent of a bomb.</p>
<p>Bottom line is once a weakness has been exposed you need to:</p>
<ul>
<li>See if it can be simply covered
<ul>
<li>Fighter can learn to defend against take downs (or not get hit in the head <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  )</li>
<li>Algorithm can be enhanced to extend its life DES==&gt;3DES</li>
</ul>
</li>
<li>Relegate
<ul>
<li>Fighter acts as the &#8216;gatekeeper&#8217; to the higher competition levels</li>
<li>Algorithms security clearance has been lowered, it cant be used in the more secure areas. Examples of this are theoretical discoveries that are likely to result in the actual weakness discover some time later.</li>
</ul>
</li>
<li>Retire
<ul>
<li>Fighter retires, becomes a commentator!</li>
<li>Algorithm depreciated as it is shown to be fundamentally insecure, now studied in university to show the weakness that designers need to be aware of. Think WEP!</li>
</ul>
</li>
</ul>
<p>If the weakness is known it is natural the opponent will attempt to get a competitive advantage using it. The longer the weakness is known the more adept the opposition will be at exploiting it.  This is true for both MMA &amp; security!</p>
<p>Companies running a SDL are the equivalent to the fighters stable. It is their job to recognize the weaknesses and manage the processes and algorithms so any weaknesses are covered or retired before they become a major problem.</p>
<p>Gareth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/09/20/how-security-is-very-much-like-mma/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQLite for C# – Part 8 – Loading CSV/Pipe into SQLite via command line</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/09/19/sqliteforcsharppart8loadingcsvpipeintosqliteviacommandline/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/09/19/sqliteforcsharppart8loadingcsvpipeintosqliteviacommandline/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 03:24:46 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=447</guid>
		<description><![CDATA[Ever wondered how hard it would be to load a CSV file into a SQLite database. I know how I would do it in code, no rocket science needed there! However in this case I wanted to really know the speed of doing this natively and really didn&#8217;t want to code anything! So looking at [...]]]></description>
			<content:encoded><![CDATA[<p>Ever wondered how hard it would be to load a CSV file into a SQLite database. I know how I would do it in code, no rocket science needed there! However in this case I wanted to really know the speed of doing this natively and really didn&#8217;t want to code anything!</p>
<p>So looking at what SQLite3.exe has too offer it pretty much supports it out of the box. Very nice <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><span style="text-decoration: underline;"><strong>Requirements:</strong></span></p>
<ul>
<li>Loading speed</li>
<li>Making the data to consuming applications available asap</li>
</ul>
<p>While I love C# and frankly its hard to go back to C or C++, sometimes performance trumps the creature comforts we have become accustomed to.</p>
<p><strong>Note:</strong> I did this without circling back to a C# implementation as I know the data and performance requirements  are tight and in this case I wanted max performance with no code! The biggest factor to a successful implementation is to ensure you use the tools best for the job, not just the ones you favor in that specific year.</p>
<p>So first things first &#8211; create a table to take the input</p>
<pre class="brush: sql;">
DROP TABLE IF EXISTS BookSales;
CREATE TABLE IF NOT EXISTS BookSales
(
   Store    int
  ,Date     varchar
  ,OrderReference varchar
  ,Line     int
  ,BookISBN varchar(14)
  ,Quantity int
  ,Price    int
, Primary Key (OrderReference,Line)
);
</pre>
<p>Next is the magic. We need to load the CSV into the table:</p>
<pre class="brush: sql;">
.separator &quot;|&quot;
.import BookSales.txt BookSales
</pre>
<p>Wow that was easy <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . You can see we set the separator to be a pipe rather than comma in this case, then the import.</p>
<p><strong>.IMPORT [FileName] [Table]</strong></p>
<p>Now the database is ready to be queried! But if we want to take it just one stage further:</p>
<pre class="brush: sql;">
.output SummaryBookSales.csv
SELECT Store, Date, BookISBN, SUM(Quantity), SUM(Price)
FROM BookSales
GROUP BY Store, Date, BookISBN;
</pre>
<p>Now we output the results of our simple aggregation into a pipe separated output file.</p>
<p>Tying this all together in a single configuration file, which we will call &#8220;BookAnalysisLoader.sql&#8221;, gives us:</p>
<pre class="brush: sql;">
DROP TABLE IF EXISTS BookSales;
CREATE TABLE IF NOT EXISTS BookSales
(
   Store    int
  ,Date     varchar
  ,OrderReference varchar
  ,Line     int
  ,BookISBN varchar(14)
  ,Quantity int
  ,Price    int
, Primary Key (OrderReference,Line)
);

.separator &quot;|&quot;
.import BookSales.txt BookSales

.output SummaryBookSales.csv
SELECT Store, Date, BookISBN, SUM(Quantity), SUM(Price)
FROM BookSales
GROUP BY Store, Date, BookISBN;
.exit
</pre>
<p>The last piece of the puzzle is the final execution:</p>
<p><strong>sqlite3.exe BookSalesAnalysis.db3 &lt; BookAnalysisLoader.sql</strong></p>
<p>Now we have a newly created database with our analysis data in it, and we have a summary CSV file generated from the output. So we can load the CSV into Excel or another DB, or directly interrogate the DB for more analytical information &#8211; and all without coding!</p>
<p><strong>Related Links:</strong></p>
<ul>
<li><a href="/technicalblog/index.php/2009/06/16/sqlite-for-c-part-1-am-i-allowed-to-use-it/">SQLite for C# &#8211; Part 1 &#8211; Am I allowed to use it?</a></li>
<li><a href="/technicalblog/index.php/2009/06/17/sqlite-for-c-part-2-how-do-i-setup-a-sqlite-db-without-coding/">SQLite for C# – Part 2 – How do I setup a SQLite DB (without coding)</a></li>
<li><a href="/technicalblog/index.php/2009/06/28/sqlite-for-c-%e2%80%93-part-3-%e2%80%93-my-first-c-app-using-sqlite-aka-hello-world/">SQLite for C# – Part 3 – My first C# app using SQLite aka Hello World</a></li>
<li><a href="/technicalblog/index.php/2009/06/30/sqlite-for-c-%e2%80%93-part-4-%e2%80%93-so-how-does-sqlite-stack-up-against-other-dbs/">SQLite for C# – Part 4 – So how does SQLite stack up against other DB’s?</a></li>
<li><a href="/technicalblog/index.php/2009/07/01/sqlite-for-c-%e2%80%93-part-5-%e2%80%93-sqlite-features-or-quirks/">SQLite for C# – Part 5 – SQLite ‘features’, or ‘quirks’</a></li>
<li><a href="/technicalblog/index.php/2009/07/02/sqlite-for-c-%e2%80%93-part-6-%e2%80%93-sqlite-connection-string-definitions/">SQLite for C# – Part 6 – SQLite Connection String Definitions</a></li>
<li><a href="/technicalblog/index.php/2009/07/05/sqlite-for-c-part-7%e2%80%93building-sqlite-net-from-source/">SQLite for C# – Part 7 – Building SQLite.Net from source</a></li>
<li>SQLite for C# – Part 8 – Loading CSV/Pipe into SQLite via command line</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/09/19/sqliteforcsharppart8loadingcsvpipeintosqliteviacommandline/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Better way to determine and police Password Strengths</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/09/13/better-way-to-determine-and-police-password-strengths/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/09/13/better-way-to-determine-and-police-password-strengths/#comments</comments>
		<pubDate>Sun, 13 Sep 2009 23:41:02 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=435</guid>
		<description><![CDATA[Perhaps my Google search mo-jo has been acting up, but I could not find a good strong C# implementation for strong passwords (in fact I really couldn&#8217;t find much outside of logical cut &#38; paste of implementations of random Information entropy implementations) . They were all predicated on the relatively standard assessment that all submitted [...]]]></description>
			<content:encoded><![CDATA[<p>Perhaps my Google search mo-jo has been acting up, but I could not find a good strong C# implementation for strong passwords (in fact I really couldn&#8217;t find much outside of logical cut &amp; paste of implementations of random Information entropy implementations) . They were all predicated on the relatively standard assessment that all submitted passwords are random &#8211; uh huh!</p>
<p>For starters I recommend reading the article [<a href="http://en.wikipedia.org/wiki/Password_strength">http://en.wikipedia.org/wiki/Password_strength</a>]. This is a good article covering the relative strengths of passwords, and gives a guide for determining the strength of a random password and a human derived password.</p>
<p>The major problem with passwords are that humans need to remember them, or they write them down. In an interesting technology twist historically you only used to  have to worry about your co-workers having access/abusing  your password because there was implicit physical security in place &#8211; you could only log on if you were physically in the office.  As such at that time your biggest threat was your co-workers, unfortunately the secondary defense of physical location has effectively been removed with the internet and VPN technology.  So now your threat count has increased from the people you work with to the entire world! Add to this these people are financially motivated and can directly target you &#8211; its a whole lot scarier out there now!</p>
<p>So before jumping into the implementations we need to go through well known things to avoid to help improve password strength:</p>
<ul>
<li>Avoid sequences &#8211; keyboard or alphabet based (abcd, qwert, 1234, !@#$% etc)</li>
<li>Avoid dictionary words, especially common ones! Be aware that common misspellings are also used in dictionary based attacks &#8211; so unless your misspelling is VERY unusual then you can expect it to be in a dictionary!</li>
<li>Avoid <a href="http://en.wikipedia.org/wiki/Leet">leet/1337</a> password substitution of words (eg P@ssw0rd, M1cr0$0ft, 0\/\/n3d). Again these are now all in dictionaries, so while it may be harder to brute force &#8211; they are pretty trivial for a dictionary attack. Of course it doesnt hurt to be 1337, but it just really doesn&#8217;t help defend a targeted attack.</li>
<li>Avoid team names, socials, license names etc.</li>
</ul>
<p>Things to avoid to minimize compromise exposure:</p>
<ul>
<li>Use different passwords for different online accounts</li>
<li>Avoid using information about you that can be readily be found on the web as a password reset scheme. DOB, where you were born, school name etc.</li>
<li>If any account needs the most rigorous password control it is your email account. Nearly every online system ties back to an email account. If you need to reset a password, it normally goes to your email address. If that is compromised then that is really the opening of Pandora&#8217;s box.</li>
</ul>
<p>Alright, lets start with the weakest &#8216;safe&#8217; approach &#8211; Information entropy:</p>
<ul>
<li>This strength calculation only holds true for &#8216;random&#8217; passwords. No human (at least that I know) can really generate a random password on their own. The best approach that I&#8217;m aware of is to start up notepad and get your two year old to start smacking your keyboard. Then take this text and randomly change case of characters and inserting special characters. Unfortunately this is still weak because we have 2 hands and the keyboard is naturally divided into where your hands go. This generation is not as randomly distributed as people would think &#8211; nor would I recommend it! But at least you have a starting point, but then you have to write it down!</li>
<li>[0-9] &#8211; 10 possible symbols per character &#8211; 3.32 bits of base2 log entropy</li>
<li>[a-z] &#8211; 26 possible symbols per character- 4.7 bits of base2 log entropy</li>
<li>[A-Z] &#8211; 26 possible symbols per character- 4.7 bits of base2 log entropy</li>
<li>[A-Z, 0-9] &#8211; 36 possible symbols per character- 5.17 bits of base2 log entropy</li>
<li>[A-Z,a-z] &#8211; 52 possible symbols per character- 5.7 bits of base2 log entropy</li>
<li>[A-Z, a-z, 0-9] &#8211; 62 possible symbols per character- 5.95 bits of base2 log entropy</li>
<li>[A-Z, a-z, 0-9, Special] &#8211; 94 possible symbols per character &#8211; 6.55 bits of base2 log entropy</li>
</ul>
<p>So we can see that having a strong password using completely random information will be hard to generate on our own, yet this approach is what is what is most commonly used to in web applications to determine password strength. This is not strong enough because humans are naturally not random. Using this  theory the following non-random passwords generate results that imply the passwords are strong:</p>
<ul>
<li>12345678901234567890 &#8211; 20*3.32 =&gt; 66.4 bits of entropy</li>
<li>!!!!!!!!!!!!!!!!!!!! &#8211; 10 * 6.55 =&gt; 65.5 bits of entropy</li>
<li>!@#$%^&amp;*() &#8211; 10 &amp; 6.55 =&gt; 65.5 bits of entropy</li>
<li>qwertyuiop[]qwertyuiop[] = 24 * 6.55 =&gt; 157.2 bits of entropy.</li>
</ul>
<p>The more astute among us will see the last two passwords were generated by running your finger across the a keyboard line of on a US keyboard. To enter the 24 characters password took under 3 seconds. So if anyone saw someone entering a password like this at work or in a library &#8211; its pretty easy to duplicate. Plainly you can see that with human users they are going to opt for the easiest way to remember and enter a password &#8211; this will never be random!</p>
<p>So to help avoid our users from becoming victims we have to try to take away the &#8216;easy&#8217; passage from them. We have to assume the password is not going to be mathematically random &#8211; so we need to start from a different position. We have to ensure we remove the human weaknesses that other &#8216;black hats&#8217; are looking to exploit.</p>
<p>So going back to the beginning of the article we are going to create an interface to define a &#8216;password policy&#8217; that provides us a way to help enforce a stronger passwords &#8211; or  at least allows systems to setup a common language for handling passwords.</p>
<pre class="brush: csharp;">
   /// &lt;summary&gt;
   /// Interface for defining a password policy
   /// &lt;/summary&gt;
   /// &lt;remarks&gt;
   /// This security policy determines whether passwords
   /// meet pre-determined complexity requirements.
   ///
   /// If this policy is enabled, passwords must meet the
   /// following minimum requirements:
   ///
   /// Not contain the user's account name or parts of the
   /// user's full name that exceed four consecutive
   /// characters.
   /// Be at least &lt;see cref=&quot;MinimumPasswordLength&quot;/&gt;
   /// characters in length
   /// Contain characters from three of the following
   /// four categories:
   /// English uppercase characters (A through Z)
   /// English lowercase characters (a through z)
   /// Base 10 digits (0 through 9)
   /// Non-alphabetic characters (for example, !, $, #, %)
   ///
   /// Complexity requirements are enforced when passwords
   /// are changed or created.
   /// &lt;/remarks&gt;
   public interface IPasswordPolicy : IPolicy
   {
      /// &lt;summary&gt;
      /// Indicates the minimum password strength index for
      /// this policy (see PasswordStrengthIndex)
      /// &lt;/summary&gt;
      /// &lt;remarks&gt;
      /// This value is based of a calculation of
      /// information entropy after sequences
      /// and dictionary words have been
      /// removed.
      /// &lt;/remarks&gt;
      /// &lt;value&gt;
      /// The minimum index of the password strength.
      /// &lt;/value&gt;
      PasswordStrengthIndex MinimumPasswordStrengthIndex
      {
         get;
         set;
      }

      /// &lt;summary&gt;
      /// Gets or sets the minimum length of the password.
      /// &lt;/summary&gt;
      /// &lt;value&gt;The minimum length of the password.&lt;/value&gt;
      int MinimumPasswordLength
      {
         get;
         set;
      }

      /// &lt;summary&gt;
      /// Gets or sets the maximum length of the password.
      /// &lt;/summary&gt;
      /// &lt;value&gt;The maximum length of the password.&lt;/value&gt;
      int MaximumPasswordLength
      {
         get;
         set;
      }

      /// &lt;summary&gt;
      /// If policy requires mixed case
      /// &lt;/summary&gt;
      /// &lt;value&gt;true if policy needs mixed case&lt;/value&gt;
      bool RequireMixedCase
      {
         get;
         set;
      }

      /// &lt;summary&gt;
      /// If policy needs digits
      /// &lt;/summary&gt;
      /// &lt;value&gt;true if policy needs digits.&lt;/value&gt;
      bool RequireDigits
      {
         get;
         set;
      }

      /// &lt;summary&gt;
      /// If policy needs special characters
      /// &lt;/summary&gt;
      /// &lt;value&gt;
      /// true if require special characters are needed
      /// &lt;/value&gt;
      bool RequireSpecialCharacters
      {
         get;
         set;
      }

      /// &lt;summary&gt;
      /// Indicates if the username needs to be additionally
      /// supplied to verify the password complexity against
      /// &lt;/summary&gt;
      /// &lt;value&gt;
      /// true require username to check password against
      /// &lt;/value&gt;
      bool RequireUsernameToCheckPasswordAgainst
      {
         get;
         set;
      }

      /// &lt;summary&gt;
      /// Gets or sets the maximum count of characters
      /// in a sequence
      /// &lt;/summary&gt;
      /// &lt;value&gt;The maximum count of characters
      /// in a sequence.&lt;/value&gt;
      int MaximumCharacterSequenceCount
      {
         get;
         set;
      }

      /// &lt;summary&gt;
      /// The duration of the lockout in minutes.
      /// &lt;/summary&gt;
      /// &lt;remarks&gt;
      /// This security setting determines the number of
      /// minutes a locked-out account remains locked
      /// out before automatically becoming unlocked.
      /// The available range is from 0 minutes through
      /// 99,999 minutes.
      /// If you set the account lockout duration to less
      /// than zero, the account will be locked out until an
      /// administrator explicitly unlocks it. If an account
      /// lockout threshold is defined, the account lockout
      /// duration must be greater than or equal to
      /// the reset time.
      /// &lt;/remarks&gt;
      /// &lt;value&gt;The duration of the lockout.&lt;/value&gt;
      int LockoutDuration
      {
         get;
         set;
      }

      /// &lt;summary&gt;
      /// Gets or sets the lockout threshold.
      /// &lt;/summary&gt;
      /// &lt;remarks&gt;
      /// This security setting determines the number of
      /// failed logon attempts that causes a user
      /// account to be locked out. A locked-out
      /// account cannot be used until it is reset
      /// by an administrator or until the
      /// lockout duration for the account has expired. You
      /// can set a value between 0 and 999 failed
      /// logon attempts. If you set the value to 0,
      /// the account will never be locked out.
      /// &lt;/remarks&gt;
      /// &lt;value&gt;The lockout threshold.&lt;/value&gt;
      int LockoutThreshold
      {
         get;
         set;
      }

      /// &lt;summary&gt;
      /// Reset account lockout after X minutes
      /// &lt;/summary&gt;
      /// &lt;remarks&gt;
      /// This security setting determines the number of
      /// minutes that must elapse after a failed logon
      /// attempt before the failed logon attempt
      /// counter is reset to 0 bad logon attempts.
      /// The available range is 1 minute to
      /// 99,999 minutes.
      /// &lt;/remarks&gt;
      /// &lt;value&gt;The duration of the lockout.&lt;/value&gt;
      int LockoutResetInMinutes
      {
         get;
         set;
      }
   }
</pre>
<p>You can see this password policy template extends the initial outline to not only provide guidance for the number of entropy bits, but allows for the policy to cover the lock out strategy in the case of incorrect password handling and password expiry approaches. If you look at the source code you will also see the options that are available, but for the sake of this article we are trying to keep on point <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>So on to the actual strength testing, this oddly is rather simple at the end of the day. We are going to use an Interface definition (IPassword) for the Password processor (makes testing &amp; mocking easier) so we can actually have multiple implementations (think <a href="http://www.codeplex.com/MEF">MEF</a>!).  Now the actual implementation.</p>
<ol>
<li>Check for sequences using various lookup tables to determine if any sequences exist. If a sequence length is detected, and is longer than allowed the password fails the policy. The tables include:
<ul>
<li>Alphabetic + numeric sequence</li>
<li>QWERTY US Keyboard</li>
<li>QWERTY UK Keyboard</li>
<li>AZERTY Keyboard</li>
</ul>
</li>
<li>Perform simple DecodeEliteEncoding then perform a simple hardcoded dictionary match of well known super common passwords</li>
<li>If supplied (and if required) compare password elements to the user name</li>
</ol>
<p>The end implementation is still fairly simple and it would be fairly easy to improve on this implementation.  The most obvious ones are to support a custom dictionary and add more custom keyboard sequences. Other extensions would be to store the passwords and become a real password token service. We can leave it up to the reader to provide an implementation of IPassword to call the Google password rating service rather than the above implementation:</p>
<p><a href="https://www.google.com/accounts/RatePassword?Passwd=csharphacker">https://www.google.com/accounts/RatePassword?Passwd=csharphacker</a></p>
<p>All good stuff! I hope this helps (and the source code) people provide a better approach to helping strengthen passwords.</p>
<p style="text-align: center;"><strong>[<a href="http://www.csharphacker.com/CSharpHacker.Utils.zip">Download source code here</a>]</strong></p>
<p>The linked source code is liable to change over time so check back often. The source code uses the Microsoft testing framework and currently has 100% code coverage! Although I don&#8217;t think 100% is all that people think it is.</p>
<p>Finally the goal is to make everything a more secure place &#8211; and in reality the best approach is to use a strong memorable password in conjunction with a hardware token that changes every minute.</p>
<p>As always feedback is welcome!</p>
<p>Gareth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/09/13/better-way-to-determine-and-police-password-strengths/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GZipStream is helpful, but has some missing features</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/07/27/gzipstream-helper-gzip/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/07/27/gzipstream-helper-gzip/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 04:07:42 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=411</guid>
		<description><![CDATA[I recently had to work around a problem in a particularly ugly way (which I wont detail ), so after that painful experience I opted to create a class to solve my specific issue in a sane and reusable manner! Out of this unexpected need the class &#8220;GZipHelper&#8221; was born. This is really just a [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to work around a problem in a particularly ugly way (which I wont detail <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ), so after that painful experience I opted to create a class to solve my specific issue in a sane and reusable manner! Out of this unexpected need the class &#8220;GZipHelper&#8221; was born. This is really just a wrapper around the  base .Net <a href="http://msdn.microsoft.com/en-us/library/system.io.compression.gzipstream.aspx">System.IO.Compression.GZipStream</a> . Its was kind of a sad day as I really didn&#8217;t want to be doing this type of wrapper code, I was hoping it would have just been nativity available in the existing GZipStream class and I could have got on with solving my real business problem at hand.</p>
<p>Firstly it should be said that the standard GZipStream stream provides the functionality I&#8217;m sure the MS engineers expected it to do, which was for HTTP based compression (at least I think that was its expected purpose). However it is certainly not a fully featured class that is really easy to use for the programmers looking to get quick &amp; helpful access to the GZip compression.</p>
<p>Specifically the problem I needed to solved was I needed to know how big any given &#8220;.GZ&#8221; decompressed file was without fully reading and decompressing the file. It seemed trivial enough &#8211; &#8220;gzip.exe -l&#8221; does what I needed, but no amount of hunting within MSDN helped. So on to the ever handy <a href="http://en.wikipedia.org/wiki/Gzip">GZip wikipedia</a> entry that detailed enough of the file format and provided the reference to the &#8220;<a href="http://tools.ietf.org/html/rfc1952">GZIP file format specification version 4.3</a>&#8220;.</p>
<p>So armed this this information we can start to decode the GZip file format to extract the length. Infact this class will check the file to see if it is GZip compressed and returns the decompressed length for that or the regular file length if it is not compressed.</p>
<p>The following class functions have been implemented (see the bottom of the article for the link to the full project):</p>
<pre class="brush: csharp;">
   /// &lt;summary&gt;
   /// Utility class to help with managing GZip (.gz) files in .Net
   /// &lt;/summary&gt;
   /// &lt;remarks&gt;
   /// This is a trivial wrapper class on top of &lt;see cref=&quot;GZipStream&quot;/&gt; that does a little magic
   /// under the covers by looking at the underlying data format and retrieves the
   /// stored data information within the GZip compressed file.
   /// &lt;/remarks&gt;
   public class GZipHelper
   {
      /// &lt;summary&gt;
      /// Gets the compressed file details
      /// &lt;/summary&gt;
      /// &lt;param name=&quot;filename&quot;&gt;The filename.&lt;/param&gt;
      /// &lt;returns&gt;True if file exists, else false&lt;/returns&gt;
      public bool GetFileDetails(string filename);

      /// &lt;summary&gt;
      /// Gets the compressed file information from a file stream
      /// &lt;/summary&gt;
      /// &lt;param name=&quot;fileStream&quot;&gt;The file stream.&lt;/param&gt;
      /// &lt;remarks&gt;
      /// Definitions provided by RFC 1952 -GZIP File Format Specification (May 1996).
      /// Coding was performed against ftp://ftp.isi.edu/in-notes/rfc1952.txt
      /// &lt;/remarks&gt;
      public void GetFileInformation(FileStream fileStream);

      /// &lt;summary&gt;
      /// Compresses the file file
      /// &lt;/summary&gt;
      /// &lt;param name=&quot;filename&quot;&gt;The filename.&lt;/param&gt;
      /// &lt;param name=&quot;overWriteExisting&quot;&gt;if set to &lt;c&gt;true&lt;/c&gt; [over write existing].&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public void CompressFile(string filename, bool overWriteExisting);

      /// &lt;summary&gt;
      /// Decompresses the file.
      /// &lt;/summary&gt;
      /// &lt;param name=&quot;filename&quot;&gt;The filename.&lt;/param&gt;
      /// &lt;param name=&quot;overWriteExisting&quot;&gt;if set to &lt;c&gt;true&lt;/c&gt; [over write existing].&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public bool DecompressFile(string filename, bool overWriteExisting);

      /// &lt;summary&gt;
      /// Returns a seekable stream into either a file or compressed file (defaults read-only)
      /// &lt;/summary&gt;
      /// &lt;remarks&gt;
      /// Decompresses the stream into a &lt;see cref=&quot;MemoryStream&quot;/&gt; if the file is compressed
      /// otherwise just returns back a regular &lt;see cref=&quot;FileStream&quot;/&gt; as a &lt;see cref=&quot;Stream&quot;/&gt;
      /// &lt;/remarks&gt;
      /// &lt;param name=&quot;filename&quot;&gt;The filename to open.&lt;/param&gt;
      /// &lt;returns&gt;Reference to opened stream&lt;/returns&gt;
      public Stream GetSeekableStream(string filename);
   }
</pre>
<p>In combination to this the following properties are available:</p>
<ul>
<li>CompressedLength &#8211; Size of the compressed file (or regular file size if not compressed)</li>
<li>DecompressedLength &#8211; Size of the file if it were uncompressed (or regular file size if not compressed)</li>
<li>IsTextFile &#8211; Indicates if GZip thought the file was text based, potentially leading to better compression</li>
<li>CompressionModeValue &#8211; Numeric indication of the compression mode used</li>
<li>CRC16Present &#8211; Indicates a CRC16 is available for the file</li>
<li>ExtraFieldsPresent &#8211; Additional meta fields are available in the file</li>
<li>FileNamePresent &#8211; GZip contains the original file name</li>
<li>FileCommentPresent &#8211; Compressed file has a comment associated with it</li>
<li>IsCompressed &#8211; Indicates if the file is GZip compressed or not</li>
<li>CompressedDate &#8211; If stored this is the date the file was compressed.</li>
<li>CRC32 &#8211; CRC32 value associated with the file</li>
</ul>
<p>Along with the project there are MSTest harnesses to test the class (trivial implementations). So the features of the class are:</p>
<ul>
<li>Can trivially determine a true file size (regardless if it was compressed via GZip or is uncompressed). This makes your code path much more readable if you are dealing with mixed file types.</li>
<li>Provides a Seekable stream into the compressed file via via a MemoryStream. The key is that you dont need to worry about the compression  (unless you are reading in BIG files) as you will get back a Stream for either a File or a Compressed file &#8211; both support seeking. This can be handy if you problem assumes it can Seek in the stream and you need to access GZip files!</li>
<li>Trivial Decompress file, this also honors the CompressedDate. If that date is set then the decompressed file has that creation date.</li>
<li>Trivial Compress file. Unfortunately at the time of writing I&#8217;ve not updated the header to include the date of the compressed file. This may come in a later version (and if so I&#8217;ll update the blog <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  &#8211; but definitely no promises!).</li>
</ul>
<p>Simple example usages are (taken straight from the unit tests!):</p>
<pre class="brush: csharp;">

// Perform a file compression
GZipHelper actual = new GZipHelper();
actual.CompressFile(_fileName, true);

// Perform a file decompression
GZipHelper actual = new GZipHelper();
string fileName = &quot;CSharpHackerSmallTest.txt.gz&quot;;
actual.DecompressFile(fileName, true);

// Get a seekable stream
GZipHelper actual = new GZipHelper();
using (Stream dataStream = actual.GetSeekableStream(&quot;CSharpHackerSmallTest.txt.gz&quot;))
{
    // Silly seek - but it just shows it can be done
    dataStream.Seek(0, SeekOrigin.Begin);
    StreamReader sr = new StreamReader(dataStream);
    string contents = sr.ReadToEnd();

    Assert.AreEqual(119, contents.Length);
}

// Gets natural decompressed file length from a compressed file.
GZipHelper actual = new GZipHelper();
actual.GetFileInformation(&quot;CSharpHackerSmallTest.txt.gz&quot;);
Assert.AreEqual(119, actual.DecompressedLength);
</pre>
<p>Finally it should be noted that by all accounts the standard implementation of GZipStream in the base .Net libraries (actually the DeflateStream) has a problem when attempting to compress random or already compressed data. There is a Microsoft Connect article [<a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93930">http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93930</a>] that details the issue.</p>
<blockquote><p>The GZipStream and DeflateStream classes can _significantly_ increase the size of &#8220;compressed&#8221; data. That means, they don&#8217;t just add a few header bytes as stand-alone compressors do, but they _inflate_ the data by as much as 50%. This is apparently because these classes do not check for incompressible data which is a standard feature of all stand-alone compressors. Both classes work fine when the data actually can be compressed.</p>
<p>Please refer to this thread for more details:</p>
<p>http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=179704&amp;SiteID=1</p></blockquote>
<p>The base implementation worked for me and met my specific needs without the need of bringing in any third party DLLs. Which incidentally also has a nice benefit for those looking to bring this into proprietary software of avoiding any licensing discussions with supervisors! If you want a more robust GZipStream implementation you can check out <a href="http://dotnetzip.codeplex.com/">http://dotnetzip.codeplex.com/</a>. This apparently has a drop in replacement, but this class could still be useful even if use this drop in replacement as well.</p>
<p>I hope this helps some one out there <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<blockquote>
<p style="text-align: center;">[<a href="http://www.csharphacker.com/GZipHelper.zip">Download GZipHelper (Source + Project) Here</a>]</p>
</blockquote>
<p>This download link will always have the latest and greatest version.</p>
<p>Gareth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/07/27/gzipstream-helper-gzip/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to write SHA256Sum in C# (or MD5Sum, SHA1Sum)</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/07/12/how-to-write-sha256sum-in-c-or-md5sum-sha1sum/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/07/12/how-to-write-sha256sum-in-c-or-md5sum-sha1sum/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 04:00:59 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=354</guid>
		<description><![CDATA[If you haven't come across MD5Sum.exe, SHA1Sum.exe, SHA256Sum.exe you can find native Windows ports here (or if you are looking for the more official GNU versions they can be found here) . Which if you are just looking for the command line tools that is probably enough. However sometimes you may have the need to do all this work yourselves in C#, if so this is the article that should help guide you! This details how to achieve ...]]></description>
			<content:encoded><![CDATA[<p>Occasionally you may have the need to create a file &#8216;fingerprint&#8217; using one of the well known and supported hash programs. The common hash algorithms are:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Md5">MD5 </a>- Dont use if you can avoid it as this is known to have vulnerabilities and should never be used!</li>
<li><a href="http://en.wikipedia.org/wiki/RIPEMD160">RIPEMD160</a> &#8211; This is supported by .Net, but isnt really heavily used. Recommend using SHA256 or SHA512</li>
<li><a href="http://en.wikipedia.org/wiki/Sha1">SHA1</a>- If you can avoid it use SHA256 or SHA512</li>
<li><a href="http://en.wikipedia.org/wiki/Sha1#SHA-2_family">SHA2 </a>Family
<ul>
<li>SHA256</li>
<li>SHA384</li>
<li>SHA512</li>
</ul>
</li>
</ul>
<p>If you haven&#8217;t come across MD5Sum.exe, SHA1Sum.exe, SHA256Sum.exe you can find native Windows ports <a href="http://blog.nfllab.com/archives/152-Win32-native-md5sum,-sha1sum,-sha256sum-etc..html">here</a> (or if you are looking for the more official GNU versions they can be found <a href="ftp://ftp.gnupg.org/gcrypt/binary/">here</a>) . Which if you are just looking for the command line tools that is probably enough. However sometimes you may have the need to do all this work yourselves in C#, if so this is the article that should help guide you!</p>
<p>First of all this is going to be fairly simple as the .Net library supports all of the above hash formats, so all we are really talking about doing is showing you the best way to use the supplied .Net runtimes to perform your hashing. So on to the magic (note to avoid width formatting issues this isnt exactly how I normally format the code!):</p>
<pre class="brush: csharp;">
/// &lt;summary&gt;
/// Performs the SHA1 Hash function on file
/// &lt;/summary&gt;
/// &lt;param name=&quot;filename&quot;&gt;
/// The filename to be hashed.
/// &lt;/param&gt;
/// &lt;returns&gt;
/// SHA1 Hash value associated with the file
/// &lt;/returns&gt;
public static string SHA1HashFile(string filename)
{
   string hashedValue = string.Empty;

   //create our SHA1 provider
   SHA1CryptoServiceProvider hashAlgorithm = new SHA1CryptoServiceProvider();

   //hash the data from the file
   byte[] hashedData = hashAlgorithm.ComputeHash(File.ReadAllBytes(filename));

   //loop through each byte in the returned byte array to convert into printed ASCII
   foreach (byte b in hashedData)
   {
      hashedValue += String.Format(&quot;{0,2:x2}&quot;, b);
   }

   //return the hashed value to the caller
   return hashedValue;
}
</pre>
<p>This does the SHA1 hashing of the supplied file &#8211; and matches the output of GNU version of SHA1Sum.exe. I told you it was simple <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Dissecting this code should be pretty trivial:</p>
<ol>
<li>Create the SHA1 Service provider (<a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha1cryptoserviceprovider.aspx">System.Security.Cryptography.SHA1CryptoServiceProvider</a>)</li>
<li>Call <a href="http://msdn.microsoft.com/en-us/library/s02tk69a.aspx">ComputeHash</a> passing in a byte array.</li>
<li>Take the results and output it as text. In case it wasnt obvious the results of the hash is a binary blob, hence the need to format it into a string friendly representation.</li>
</ol>
<p>However there are really 2 problems with this code:</p>
<ol>
<li>File.ReadAllBytes &#8211; This returns a byte array of the file &#8211; pretty much as you would expect! The problem is that if this is a very big file, for example a hash for a DVD, the entire file needs to be loaded into memory before it gets hashed. Obviously not the most optimal approach!</li>
<li>This is completely locked into SHA1, you need a new function for any other different hashing function. Not a biggie, but it would be nice to  get some reuse in now and then. Definitely useful if you see the full example where we have to use some fall back processing if an algorithm is not available.</li>
</ol>
<p>Thankfully fixing this is still pretty trivial. To fix issue 1 rather than using the ComputeHash that takes in the byte array, use the one that takes the stream. This avoids the need for having the entire file in memory before the hash process can start. Out of curiosity I looked up the publicly available source code for the function to check it was in fact doing what I thought. Thankfully it is simple and obvious:</p>
<pre class="brush: csharp;">
...
// Default the buffer size to 4K.
byte[] buffer = new byte[4096];
int bytesRead;
do {
   bytesRead = inputStream.Read(buffer, 0, 4096);
   if (bytesRead &gt; 0) {
     HashCore(buffer, 0, bytesRead);
  }
} while (bytesRead &gt; 0);
...
</pre>
<p>So we can see when we use the stream version of <a href="http://msdn.microsoft.com/en-us/library/xa627k19.aspx">HashAlgorithm.ComputeHash Method (Stream)</a> it only will use up a small memory chunk for calculating the hash values. So we are safe from big files from potentially killing the application.</p>
<p>Issue 2 &#8211; The .Net team did a nice job of creating base classes, one of which is <a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.hashalgorithm.aspx">HashAlgorithm</a>. This is actually the class that implements the hashing &#8216;interface&#8217;. All hash algorithms must derive from this class. So we can use this to our advantage:</p>
<pre class="brush: csharp;">
/// &lt;summary&gt;
/// Performs a Hash operation on the supplied file.
/// &lt;/summary&gt;
/// &lt;param name=&quot;filename&quot;&gt;
/// The filename to be hashed.
/// &lt;/param&gt;
/// &lt;returns&gt;
/// Selected Hash value associated with the file
/// &lt;/returns&gt;
public static string HashFile(
          string filename
          , HashAlgorithm hashAlgorithm)
{
   if (!File.Exists(filename))
   {
      throw new ArgumentException(filename + &quot; must exist&quot;, &quot;filename&quot;);
   }

   string hashedValue = string.Empty;
   byte[] hashedData = null;

   // Create the stream
   using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read))
   {
      hashedData = hashAlgorithm.ComputeHash(fs);
   }

   //loop through each byte in the returned byte array
   foreach (byte b in hashedData)
   {
      //convert each byte and append
      hashedValue += String.Format(&quot;{0,2:x2}&quot;, b);
   }

   //return the hashed value
   return hashedValue;
}
</pre>
<p>Now we have a generic function to return back a hash value from any supported .Net hash algorithm. To call it you could just do &#8220;HashFile(filename,new SHA1CryptoServiceProvider())&#8221;. Voila! Performance and can trivially support any hashing class the .Net framework implements.</p>
<p>Ok so lets get a little more adventurous now. Attached to this entry is a very simple (aka not fully featured) HashSum source code that allows the same executable to be used to provide all the above hashing! However as a word of caution you need to be a little careful with the more advanced hashing. For example Microsoft supply both &#8220;SHA256CryptoServiceProvider&#8221; and &#8220;SHA256Managed&#8221;. On the surface they look pretty much the same, apart from SHA256CryptoServiceProvider is only available in .Net 3.5 (or higher). However since this uses Operating system cryptographic service providers they may not be available on the platform your program is running on. If that is the case then you will get the PlatformNotSupportedException exception thrown:</p>
<pre class="brush: plain;">
System.PlatformNotSupportedException was unhandled
  Message=&quot;The specified cryptographic algorithm is not supported on this platform.&quot;
  Source=&quot;System.Core&quot;
  StackTrace:
       at System.Security.Cryptography.CapiNative.AcquireCsp(String keyContainer, String providerName, ProviderType providerType, CryptAcquireContextFlags flags, Boolean throwPlatformException)
       at System.Security.Cryptography.CapiHashAlgorithm..ctor(String provider, ProviderType providerType, AlgorithmId algorithm)
       at System.Security.Cryptography.SHA256CryptoServiceProvider..ctor()
       at CSharpHacker.Hash.HashSum.Main(String[] args) in X:\GIT\FileHash\FileSum.cs:line 76
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:
</pre>
<p>Hmmm &#8211; you don&#8217;t read about that little chestnut in the MSDN help! So if you know you are going to only be running this on a Windows 2008, Vista or Windows 7 or later you can just use the &#8220;SHA256CryptoServiceProvider&#8221; version. However if you may have to support systems such as XP (potentially Windows 2003 as well) you will have to use the Managed versions. The safest route would be to provide a graceful fall back mechanism (possibly with a warning) that the CSP version could not be used and using the managed code version instead. This provides the best of both worlds, if the platform supports the CSP version you can use that (which should give you a speed increase) or you use the managed solution.</p>
<pre class="brush: csharp;">
case &quot;SHA256SUM&quot;:
default:
   try
   {
      hashAlgorithm = new SHA256CryptoServiceProvider();
   }
   catch (PlatformNotSupportedException)
   {
      // Fall back to the managed version if the CSP
      // is not supported on this platform.
      hashAlgorithm = new SHA256Managed();
   }
   break;
</pre>
<p>This is a second benefit of using the &#8220;HashAlgorithm&#8221; approach, the underlying code responsible for the generic hashing function is that it doesnt need to know what version (or even algorithm) it is using.</p>
<p>You also have to bear in mind that if you are going to use &#8220;SHA256CryptoServiceProvider&#8221; (or equivalent) you have to be using .Net 3.5 or greater.</p>
<p><a href="/FileSum.zip">Click to download Sample CSharp FileSum project</a></p>
<p>This is a .Net 3.5 project that based off the executable file name it uses that algorithm. So if you rename FileSum.exe to &#8220;SHA512Sum.exe&#8221; it will perform the SHA512 hash on the input file, MD5Sum.exe MD5 hash, etc. If the name is not a recognized name it defaults to using the SHA256 algorithm. This is not designed to be a wholesale replacement for SHA256Sum etc, but more of a guide how to write a fully featured version. So things missing from this include (and are not limited to <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ):</p>
<ul>
<li><span style="text-decoration: line-through;">No support for wildcards (simple enough to add but not there)</span></li>
<li>No support for checking files match the input file (&#8216;-c or &#8211;check&#8217;)</li>
<li>Only binary mode is supported, no support for ASCII/Text mode. No support for &#8216;-t&#8217; or &#8216;&#8211;text&#8217;</li>
<li>No support for standard input processing</li>
</ul>
<p>Hope you found this useful,</p>
<p>Gareth</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 3036px; width: 1px; height: 1px;">
<pre>is not supported</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/07/12/how-to-write-sha256sum-in-c-or-md5sum-sha1sum/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
