<?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</title>
	<atom:link href="http://www.csharphacker.com/technicalblog/index.php/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>SQLite 3.7.0 Released &#8211; WAL is now available</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2010/07/21/sqlite-3-7-0-released-wal-is-now-available/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2010/07/21/sqlite-3-7-0-released-wal-is-now-available/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 02:15:05 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=506</guid>
		<description><![CDATA[The official release information can be found [SQLite Release 3.7.0 On 2010 July 22 (3.7.0)]. The summary is that this is a pretty large change compared to previous releases. WAL (Write Ahead Logging) support &#8211; this means: Generally faster More concurrency Better disk performance when processing the WAL logs. Cant use network shares or different [...]]]></description>
			<content:encoded><![CDATA[<p>The official release information can be found [<a href="http://www.sqlite.org/releaselog/3_7_0.html">SQLite Release 3.7.0 On 2010 July 22 (3.7.0)</a>]. The summary is that this is a pretty large change compared to previous releases.</p>
<ul>
<li>WAL (Write Ahead Logging) support &#8211; this means:
<ul>
<li>Generally faster</li>
<li>More concurrency</li>
<li>Better disk performance when processing the WAL logs.</li>
<li>Cant use network shares or different computers for writing to the same logs.</li>
<li>[<a href="http://www.sqlite.org/wal.html">Complete WAL information can be found here</a>]</li>
</ul>
</li>
<li>Query planner enhancement</li>
<li>Logical database size is now stored in the database header so that      bytes can be appended to the end of the database file</li>
</ul>
<p>Well done to the SQLite team!</p>
<p>Gareth</p>
<p>PS And for those wondering, I will restart blogging again on a more regular basis very soon, just been unburying myself!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2010/07/21/sqlite-3-7-0-released-wal-is-now-available/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Handy SQL Server knowledge nuggets</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2010/01/24/handy-sql-server-knowledge-nuggets/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2010/01/24/handy-sql-server-knowledge-nuggets/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 04:40:32 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[SQLServer]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=499</guid>
		<description><![CDATA[These are worth reading, kind of a read once &#8211; nothing too complicated. However they will be useful if you have the need for these [How to find out what procedure is doing a data modification] Very simple, yet effective approach to determine what RPC call is altering your data. This is a read it [...]]]></description>
			<content:encoded><![CDATA[<p>These are worth reading, kind of a read once &#8211; nothing too complicated. However they will be useful if you have the need for these</p>
<ul>
<li><a href="http://sqlblogcasts.com/blogs/antxxxx/archive/2009/10/13/how-to-find-out-what-procedure-is-doing-an-insert.aspx">[How to find out what procedure is doing a data modification</a>]
<ul>
<li>Very simple, yet effective approach to determine what RPC call is altering your data. This is a read it once, you get the ah-ha why didn&#8217;t I think of that moment and you wont need to reference it again!</li>
</ul>
</li>
<li>[<a href="http://sqlblog.com/blogs/jamie_thomson/archive/2009/11/25/temporary-procedures-sql-server.aspx">Temporary procedures : T-SQL</a>]
<ul>
<li>We all know about temporary tables, but you can do that for stored procedures as well. Neat if you have a need for it</li>
</ul>
</li>
<li>[<a href="http://blogs.msdn.com/conor_cunningham_msft/archive/2009/11/12/conor-vs-foreign-key-join-elimination.aspx">Conor vs. FOREIGN KEY join elimination</a>]
<ul>
<li>Explains a bit of the history why a single column foreign key performs better than a multi-column FK. Its the old 80:20 rule at work, or probably more accurately 99.9:0.1 rule <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ul>
</li>
<li>[<a href="http://sqlblogcasts.com/blogs/repieter/archive/2009/11/17/ssrs-report-execution-failed-solution-sspi-ntlm.aspx">SSRS -Report execution failed. Solution: SSPI=NTLM</a>]
<ul>
<li>Seems downgrading to NTLM solves some integrated security issues if Kerberos is not playing nicely. Handy to know.</li>
</ul>
</li>
<li>[<a href="http://sqlblogcasts.com/blogs/tonyrogerson/archive/2009/11/24/taking-advantage-of-table-variables-not-being-transactional-application-logging-files-within-a-transaction-and-keeping-what-s-happened.aspx">Take advantage of Table Variables NOT being transactional</a>]
<ul>
<li>Ever needed to store state in a transaction that you didnt want to be rolled back? Think log tables! Read and learn <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ul>
</li>
<li>[<a href="http://blog.sqlauthority.com/2010/01/12/sql-server-fragmentation-detect-fragmentation-and-eliminate-fragmentation/">SQL SERVER – Fragmentation, Detection and how to resolve it</a>]
<ul>
<li>Nice overview of fragmentation, and shows how to use DMV&#8217;s rather than the old school SQL 2000 DBCC approaches <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ul>
</li>
<li>[<a href="http://sys2dmvs.codeplex.com/">CodePlex: SYS2 DMVs</a>]
<ul>
<li>Hopefully this will serve as a good collection point &#8211; its very &#8216;young&#8217; at the moment, but I would like it to live!</li>
</ul>
</li>
<li>[<a href="http://blogs.msdn.com/sqlserverstorageengine/archive/2010/01/18/improvement-in-minimizing-lockhash-key-collisions-in-sql-server-2008r2-and-its-impact-on-concurrency.aspx">Locking improvements in SQL 2008 R2</a>]
<ul>
<li>Handy to know about, unfortunately R2 has a price hike associated with it <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </li>
</ul>
</li>
<li>[<a href="http://weblogs.sqlteam.com/mladenp/archive/2010/01/21/SQL-Server-ndash-Find-the-most-expensive-operations-in-Execution.aspx">Find the most expensive operations in Execution plans</a>]
<ul>
<li>Handy way to take the XML plan and process it in a way to get a tabular list of the most expensive queries back. Very nice.</li>
</ul>
</li>
</ul>
<p>I suspect everyone who has dealt with scalar UDF functions in production environments are already VERY aware of the performance sucking capability they can have on your nice server. Here are some nice comments if you are not painfully aware:</p>
<ul>
<li>[<a href="http://www.simple-talk.com/community/blogs/tony_davis/archive/2009/11/13/76413.aspx">Do Scalar UDFs give SQL Server a Bad Name?</a>]</li>
<li>[<a href="http://sqlblogcasts.com/blogs/sqlandthelike/archive/2009/10/15/udf-overhead-a-simple-example.aspx">UDF Overhead – A simple example</a>]</li>
</ul>
<p>Gareth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2010/01/24/handy-sql-server-knowledge-nuggets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2010 &#8211; 2012 Technology Predictions</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2010/01/23/2010-2012-technology-predictions/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2010/01/23/2010-2012-technology-predictions/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 03:38:28 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=493</guid>
		<description><![CDATA[I was celebrating 10 years after the dreaded Y2K down in Florida this year and was wondering if I would dare to write down my technology predictions. So feeling bold here they are, only time will tell if I&#8217;m anywhere close to accurate : Cloud Authorization Death of smart clients No-SQL and ORM BI becomes [...]]]></description>
			<content:encoded><![CDATA[<p>I was celebrating 10 years after the dreaded Y2K down in Florida this year and was wondering if I would dare to write down my technology predictions. So feeling bold here they are, only time will tell if I&#8217;m anywhere close to accurate <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  :</p>
<ul>
<li>Cloud</li>
<li>Authorization</li>
<li>Death of smart clients</li>
<li>No-SQL and ORM</li>
<li><a href="http://en.wikipedia.org/wiki/Business_intelligence">BI</a> becomes commodity</li>
<li>Netbooks &#8211; and the Google &#8216;netbook&#8217;</li>
<li>Deployment</li>
<li>SVN ==&gt; GIT or Mercurial</li>
</ul>
<h3>Cloud</h3>
<p>No surprises here, with Amazon running this model &#8216;forever&#8217;, Google not too far behind and now even Microsoft has started to chime in as well. The are alliances and definitions for SaaS, IaaS, PaaS. This concept is here to stay, and in fact will affect us in significant ways.</p>
<h3>Authorization/Authentication</h3>
<p>This is the big play that will help make the cloud be really viable, and even work with managing external companies that need to work for your company (think PCI compliance and support). This model will be based on the claims concept that has been knocking around for a while now, all it needed was something to push it into the limelight. Clouds have started to push authorization / authentication! In addition when this matures to a &#8216;tipping point&#8217; I have no doubt customers will start to &#8216;outsource&#8217; their claims trust (with contractual backup!) to other companies. For example if your company needs to provide PCI support to a customer, today the customer will have to be provided the peoples names and assign them logon accounts and manage their passwords. This becomes a major overhead and can be relatively easily managed through a claims based authorization system. Naturally this wont happen within two years &#8211; but it is coming!</p>
<h3>Death of Smart Clients</h3>
<p>Companies will realize that Smart Clients (aka Prism, Click-Once web forms) are only a stop gap. Browsers will rule the application space within 5 years, and will have made significant inroads before 2012. Conceptually they all make sense, but in today&#8217;s platform varied world they are dead &#8211; but it seems not everyone realizes it yet!</p>
<h3>No-SQL / ORM</h3>
<p>It seems that there are two factors pushing these forwards, but the root of it is that the historical relational database has so much overhead associated with infrastructure, management and DBA&#8217;s &#8211; people are looking for alternatives. It has become increasingly common for application programmers to fear the rules of relational databases they have to integrate with as they have evolved into their own discipline. This leads into ORM and which really try to &#8216;ignore&#8217; the storage mechanism and provide plain business value. The No-SQL group are in a similar boat, they are interested in scaling and maintainance and know traditional relational models don&#8217;t meet their business needs.</p>
<h3><a href="http://en.wikipedia.org/wiki/Business_intelligence">BI</a> becomes a Commodity</h3>
<p>Microsoft has been playing the &#8220;BI is coming, BI is coming&#8221; song for a while now. However it seems with the SQL 2008 R2 release we are starting to get commodity solutions. This in intern will coerce the competitors to step up. The good news for competitors is that Microsoft has got more pricey, its no longer the &#8216;cheap kid on the block&#8217;. Open Source is starting to catch up with its commercial cousins. Either way its going to be an interesting couple of years for BI.</p>
<h3>Netbooks &#8211; and the Google one</h3>
<p>We have heard the term many times before, and even had a couple of false starts. The difference now is:</p>
<ol>
<li>Processing power has significantly cheapened &#8211; allowing more inexpensive offerings</li>
<li>Web/Cloud infrastructure is in place. No worries about email or docs being stored on line.</li>
</ol>
<p>So we have pretty good netbooks now, but I suspect Google will potentially set the standard for the netbooks. If done right (as opposed to the Nexus!) they have a killer combination. This is one I&#8217;m really interested to see what happens!</p>
<h3>Deployment</h3>
<p>Vista didnt get much traction and XP is on its last officially supported legs, as such I suspect that companies will be rolling out Windows 7 over the next 2-3 years. This will stress the deployment tools, and require individuals that know deployment to step in. In addition to this Windows Server 2008 R2 only comes in 64 bit &#8211; software houses realize the time has come to admit they are going to have to invest in supporting 64 bit solutions. This is going to be unusual for customers as they have forgotten how to roll out such changes as it has been a while since the last great deployment upgrade. There will be lots of opportunities in this area!</p>
<h3>SVN ==&gt; GIT / Mercurial</h3>
<p>It seems that the CVS savior is in the process of being usurped by the <a href="http://en.wikipedia.org/wiki/Distributed_revision_control">DVCS</a> products. Specially GIT and <a href="http://mercurial.selenic.com/">Mercurial</a> are the strong runners. Its a shame because I had waited a while for SVN to mature to a point and now GIT &amp; Mercurial are eating up projects. Oddly at the time of writing this even the Microsoft sponsored <a href="http://blogs.msdn.com/codeplex/archive/2010/01/22/codeplex-now-supporting-native-mercurial.aspx">CodePlex site now supports Mercurial</a> !</p>
<p>Finally the one I didn&#8217;t add to the list is software parallelism programming models. I suspect this will mature with all the new multi-core processors that are coming out. However I think this will mature after 2012 <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Gareth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2010/01/23/2010-2012-technology-predictions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<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>Links to Software Security Code reviews</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2010/01/15/links-to-security-code-reviews/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2010/01/15/links-to-security-code-reviews/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 02:48:16 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=480</guid>
		<description><![CDATA[Here is a link of helpful links if you want to double check your existing security code process (y&#8217;all do have them &#8211; right?): [OWASP Code Review] [How To: Perform a Security Code Review for Managed Code] [Phase 1: Conduct a Security Design Review] [Security Code Reviews] Note as other are suggested, or I find [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a link of helpful links if you want to double check your existing security code process (y&#8217;all do have them &#8211; right?):</p>
<ul>
<li>[<a href="http://www.owasp.org/index.php/OWASP_Code_Review_Guide_Table_of_Contents">OWASP Code Review</a>]</li>
<li>[<a href="http://msdn.microsoft.com/en-us/library/ms998364.aspx">How To: Perform a Security Code Review for Managed Code</a>]</li>
<li>[<a href="http://blogs.msdn.com/ace_team/archive/2009/10/19/dogfooding-how-microsoft-it-information-security-dogfoods-phase-1-conduct-a-security-design-review.aspx">Phase 1: Conduct a Security Design Review</a>]</li>
<li>[<a href="http://www.codesecurely.info/Wiki/view.aspx/Security_Code_Reviews">Security Code Reviews</a>]</li>
</ul>
<p>Note as other are suggested, or I find others I&#8217;ll update the list.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2010/01/15/links-to-security-code-reviews/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQLite updated webpage&#8230; now has search! Happy New Year!</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2010/01/08/sqlite-updated-webpage-now-has-search-happy-new-year/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2010/01/08/sqlite-updated-webpage-now-has-search-happy-new-year/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 02:46:14 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=477</guid>
		<description><![CDATA[It seems the SQLite folks have added a significant, needed and often requested, feature to the SQLite site.  No the change we are talking about has nothing to do with the SQLite engine, but yes I&#8217;m talking about the web site. In the top right side of the website there is a new shiny unobtrusive [...]]]></description>
			<content:encoded><![CDATA[<p>It seems the SQLite folks have added a significant, needed and often requested, feature to the SQLite site.  No the change we are talking about has nothing to do with the SQLite engine, but yes I&#8217;m talking about the web site. In the top right side of the website there is a new shiny unobtrusive &#8220;Search SQLite Docs&#8230;&#8221; search box.</p>
<p>So for all us who have spent time searching, or had pages pointed out to us <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> , for options  this is an excellent new years present!</p>
<p>Many thanks to the SQLite guys for both their product, and their handy dandy search feature!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2010/01/08/sqlite-updated-webpage-now-has-search-happy-new-year/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Welcome to the Google Wave &#8211; what is the wave (and where is the board)&#8230;</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/11/18/welcome-to-the-google-wave-what-is-the-wave-and-where-is-the-board/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/11/18/welcome-to-the-google-wave-what-is-the-wave-and-where-is-the-board/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 06:02:34 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[HandyTech]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=474</guid>
		<description><![CDATA[This weekend I was officially invited accepted to join the Google Wave. While I was feeling fairly happy with myself I was wondering what to do with the 8 invites I got as well. Luckily for me others I know also got the invite at the same time (guess they lowered the requirements ). Ok [...]]]></description>
			<content:encoded><![CDATA[<p>This weekend I was officially <span style="text-decoration: line-through;">invited</span> accepted to join the Google Wave. While I was feeling fairly happy with myself I was wondering what to do with the 8 invites I got as well. Luckily for me others I know also got the invite at the same time (guess they lowered the requirements <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ). Ok for those hiding in a cave or haven&#8217;t heard about the buzz, here is what Wave is meant to be:</p>
<blockquote><p>&#8220;Google Wave is an online tool for real-time communication and collaboration. A wave can be both a conversation and a document where people can discuss and work together using richly formatted text, photos, videos, maps, and more.&#8221;</p></blockquote>
<p>This is the email that hit my in box across the weekend.<br />
<img class="aligncenter size-full wp-image-475" title="Wave Invite Email" src="http://www.csharphacker.com/technicalblog/wp-content/uploads/2009/11/Wave_Invite.jpg" alt="Wave Invite Email" width="708" height="243" /></p>
<p>After playing with the software me its like a communal no holds barred whiteboard &#8211; but with history tracking. However this whiteboard is written text, graphics, videos etc. People can read or help contribute/refine the whiteboard &#8211; which is known in Google terms as a &#8220;Wave&#8221;. People can be invited late into the Wave, and quickly catchup (or back track depending on your perspective) using the history tracking feature. A friend described is as &#8220;cross between a wiki/twitter/blog/im/email.&#8221; Its certainly an interesting concept and I can actually see it working well in a number of cases.</p>
<p>Playing with it is certainly revealing and you can quickly see the high level implications of it, but you definitely need either a small group of folks needing to solve a &#8220;problem&#8221; (be it a BBQ cook out that needs organizing, or a technical design) to really benefit from this collaboration tool (at this time), or you need more adoption to get people to use it more.</p>
<p>Frankly this is pretty exciting &#8211; I just need to get a reason/project to use it in more anger now <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>More information can be found at this [<a href="http://wave.google.com/help/wave/about.html">About Google Wave</a>], and the key to its success will be its &#8220;Add-in&#8221; extensions and the underlying API. I believe the most valuable parts of this whole thing is the API backbone used to power &#8220;Wave&#8221;, and how far browsers can be pushed to support these very dynamic collaborative applications.</p>
<p>The standard warning however is, this is not production, nor it is even &#8220;Beta&#8221;, this is &#8220;Preview&#8221;! So dont put all your eggs in the basket without a backup/backout plan!</p>
<p>Gareth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/11/18/welcome-to-the-google-wave-what-is-the-wave-and-where-is-the-board/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SQL News &#8211; and the fact we have to go to 64 bit and more $</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/11/14/sql-news-and-the-fact-we-have-to-go-to-64-bit-and-more/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/11/14/sql-news-and-the-fact-we-have-to-go-to-64-bit-and-more/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 02:22:02 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[SQLServer]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=471</guid>
		<description><![CDATA[Everyone should know now that there has been a massive amount of Microsoft activity. This article will cover the recent SQL activity, including end of service dates, x64 requirements, and a fairly significant price hike. The tipping point is...]]></description>
			<content:encoded><![CDATA[<p>Everyone should know now that there has been a massive amount of Microsoft activity. This article will cover the recent SQL activity, however the big one really is that the tipping point for 64 bit is in progress. This is a shame for me as I&#8217;m running 32bit OS, and I&#8217;m going to have to pave my machine &#8211; but that is the price developers are going to have to pay to play!</p>
<ul>
<li>[<a href="http://www.microsoft.com/sqlserver/2008/en/us/R2-editions.aspx">What's New in SQL Server 2008 R2 Editions</a>]
<ul>
<li>Biggest first &#8211; Price increase! To say I&#8217;m disappointed is an understatement in this area. Specifically for developers  already have to support 2005 &amp; 2008. Now they have to deal with R2, and persuade their customers to move to R2 if they want certain features.</li>
<li>MDS &#8211; Master Data Services &#8211; more on this one later. Pretty cool</li>
<li>Parallel Data Warehouse release
<ul>
<li>The DATAllegro purchase is now seeing the light as a Microsoft product!</li>
<li>Support of very large datasets (100Tb-1Pb). This is definitely something I would like to play with, but at $57,496 per processor&#8230;</li>
</ul>
</li>
<li>Standard now has backup compression &#8211; but with the price tag&#8230;</li>
</ul>
</li>
<li>[<a href="http://blogs.msdn.com/sqlrsteamblog/archive/2009/11/09/sql-server-2008-r2-november-ctp-what-s-new-in-reporting-services.aspx">SQL Server 2008 R2 November CTP – What’s New In Reporting Services?</a>]
<ul>
<li>Report Builder 3.0 is available! Woohoo!</li>
<li>Enhanced sharepoint integration</li>
<li>Aggregates of aggregates</li>
<li>New Data Visualization Report Items</li>
</ul>
</li>
<li>[<a href="http://sqlcat.com/msdnmirror/archive/2009/10/20/using-filtered-statistics-with-partitioned-tables.aspx">Using Filtered Statistics with Partitioned Tables</a>]
<ul>
<li>Learn to appreciate filtered statistics!</li>
</ul>
</li>
<li>[<a href="http://sqlblog.com/blogs/jamie_thomson/archive/2009/11/13/mds-is-x64-only.aspx">MDS (Master Data Services) is x64 Only</a>]
<ul>
<li>I totally get this, but this is the tipping point for me to repave my machines <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </li>
<li>With this requiring x64 and many new products requiring Windows 2008, Windows 7 or Vista it seems now is the time to move up.</li>
</ul>
</li>
<li>[<a href="http://blogs.msdn.com/sqlreleaseservices/archive/2009/10/08/end-of-service-pack-support-for-sql-server-2005-sp2-and-sql-server-2008-rtm.aspx">MSSQL End of service dates for Service packs</a>]
<ul>
<li>Support for SQL Server 2005 Service Pack 2 (SP2)  will end on <strong>January 12, 2010</strong></li>
<li>Support for SQL Server 2008 RTM will end on <strong>April 13, 2010</strong></li>
</ul>
</li>
</ul>
<p>More to come!</p>
<p>Gareth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/11/14/sql-news-and-the-fact-we-have-to-go-to-64-bit-and-more/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What the heck is redacting a database?</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/10/21/what-the-heck-is-redacting-a-database/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/10/21/what-the-heck-is-redacting-a-database/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 02:04:26 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[SQLServer]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=469</guid>
		<description><![CDATA[A good friend of mine sent me the following link: [http://www.codersrevolution.com/index.cfm/2009/10/21/Sequoia-Voting-System-Witch-Hunt-err-Study-Project"] The learning we can take away from this is if you don&#8217;t adequately cleanse then you can expect the data to become available! While its an interesting concept they apparently tried (and not too successfully) to do. The best way to clean a database [...]]]></description>
			<content:encoded><![CDATA[<p>A good friend of mine sent me the following link:</p>
<p>[<a href="http://www.codersrevolution.com/index.cfm/2009/10/21/Sequoia-Voting-System-Witch-Hunt-err-Study-Project">http://www.codersrevolution.com/index.cfm/2009/10/21/Sequoia-Voting-System-Witch-Hunt-err-Study-Project"</a>]</p>
<p>The learning we can take away from this is if you don&#8217;t adequately cleanse then you can expect the data to become available! While its an interesting concept they apparently tried (and not too successfully) to do. The best way to clean a database is to create a new one and just copy in the data you want exposed. Don&#8217;t trust the handy dandy DROP/DELTE <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>If they wanted to expose/publish the 88 tables, then they should have created a new DB, copied in the tables and released it. Anything less than that you have to be VERY careful! And for the more security conscious it would be created on a recently wiped drive on a recently rebooted computer!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/10/21/what-the-heck-is-redacting-a-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Datawarehousing news and nice approach for partitioned data</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/09/30/datawarehousingandpartitioneddata/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/09/30/datawarehousingandpartitioneddata/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 00:01:39 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[Data Warehousing]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=466</guid>
		<description><![CDATA[[Kickfire Offers Data Warehouse Appliance for the Masses] Kickfire supports a MySQL based data-warehouse appliance targeting 500Gb -5Tb range, starting at $32K. Will have to start monitoring this one. They appear to use similar concept to Netezza by utilizing SQL in hardware for speed, not exactly the same &#8211; but interesting to see the appliance [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li>[<a href="http://intelligent-enterprise.informationweek.com/showArticle.jhtml?articleID=220300604">Kickfire Offers Data Warehouse Appliance for the Masses</a>]
<ul>
<li><a href="http://www.kickfire.com/">Kickfire</a> supports a MySQL based data-warehouse appliance targeting 500Gb -5Tb range, starting at $32K.</li>
<li>Will have to start monitoring this one. They appear to use similar concept to Netezza by utilizing SQL in hardware for speed, not exactly the same &#8211; but interesting to see the appliance trend.</li>
</ul>
</li>
<li>[<a href="http://sldn.softlayer.com/09/2009/building-the-data-warehouse/">Building the Data Warehouse for bandwidth tracking</a>]
<ul>
<li>This is a worthy read if you need to load and handle lots of naturally partitioned data</li>
<li>For those not willing to read, I&#8217;ll pose a question &#8211; how would you handle 683,460 tables <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/09/30/datawarehousingandpartitioneddata/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>Interesting stuff 2009-09-20</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/09/20/interesting-stuff-2009-09-20/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/09/20/interesting-stuff-2009-09-20/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 05:30:53 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=458</guid>
		<description><![CDATA[8 topics that I&#8217;ve been tracking, and now have the time to do the &#8216;cliff notes&#8217; for: [MSSQL - The Query Optimizer and Parameter Sniffing] If you dont know about query sniffing, or came across it a couple of years ago and have forgotten. Give this a (re)read. The key here is the &#8220;Optimize&#8221; for [...]]]></description>
			<content:encoded><![CDATA[<p>8 topics that I&#8217;ve been tracking, and now have the time to do the &#8216;cliff notes&#8217; for:</p>
<ul>
<li>[<a href="http://sqlblog.com/blogs/ben_nevarez/archive/2009/08/27/the-query-optimizer-and-parameter-sniffing.aspx">MSSQL - The Query Optimizer and Parameter Sniffing</a>]
<ul>
<li>If you dont know about query sniffing, or came across it a couple of years ago and have forgotten. Give this a (re)read.</li>
<li>The key here is the &#8220;Optimize&#8221; for a typical parameter, I dont recall this existing in 2000. So if you are stuck with 2000 (you know who you are!), this obviously wont work!</li>
</ul>
</li>
<li>[<a href="http://blog.paul-mason.co.nz/2009/09/protecting-your-precious-code-naming.html">Need to protect your C# code? Have a look at nCloak</a>]
<ul>
<li>Article covering how nCloak does naming.</li>
<li>This isnt production ready, but if you have spare time it would be interesting to see how far this project can go.</li>
<li>This shows the benefit that Mono is bringing to the C# world!</li>
</ul>
</li>
<li>[<a href="http://martinfowler.com/bliki/FeatureBranch.html">Just got onto TFS? Ready to try GIT/Mercurial? Read more about branch strategies in DVCS</a>]
<ul>
<li>Seems like only yesterday everyone was moving from VSS to TFS. Now GIT and Mercurial are on the scenes.</li>
<li>This article covers various strategies for CI or even &#8220;Promiscuous Integration&#8221;</li>
<li>Interestingly the DVCS (Distributed Version Control Systems) appear better suited to OSS projects than internal corporate ones.</li>
</ul>
</li>
<li>[<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=0fcba3c7-bc30-47b0-a2f8-2e702720998a&amp;displaylang=en">Microsoft SDL Developer Starter Kit</a>]
<ul>
<li>The Microsoft SDL Developer Starter Kit provides a compliation of baseline developer security training materials on core Microsoft Security Development Lifecycle (SDL) topics.</li>
</ul>
</li>
<li>[<a href="http://www.ossec.net/main/about/">OSSEC - open source Host-based Intrusion Detection System (HIDS)</a>]
<ul>
<li>Its free! 2.2 came out September 8, 2009</li>
<li>It has a powerful correlation and analysis engine, integrating log analysis, file integrity checking, Windows registry monitoring, centralized policy enforcement, rootkit detection, real-time alerting and active response.</li>
</ul>
</li>
<li>[<a href="http://blogs.msdn.com/sdl/archive/2009/09/16/two-new-security-tools-for-your-sdl-tool-belt-bonus-a-7-easy-steps-whitepaper.aspx">Microsoft releases mini-Fuzzer &amp; Binary analyzer</a>]
<ul>
<li>Finally <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> , MS have released some simple fuzzers to help developers understand what they are facing from the black hats!</li>
</ul>
</li>
<li>[<a href="http://www.net-security.org/secworld.php?id=8119">IT executive going to China? If you follow the guidance it will be expensive!</a>]
<ul>
<li>Paraphrasing this short article wont do it justice.  Among the measures it recommends to IT executives regarding the protection of their computer equipment when traveling to that country are (wow is about all I can say!):</li>
</ul>
<ul>
<li>
<ul>
<li>Leave your standard IT equipment at home &#8211; buy separate gear to use in China</li>
<li>Weigh the machine before you go and when you get back</li>
<li>&#8220;Clean&#8221; thoroughly the equipment (re-image the laptop you used)</li>
<li>Throw away the mobile phone you used during your stay.</li>
</ul>
</li>
</ul>
</li>
<li>[<a href="http://consultingblogs.emc.com/simonmunro/archive/2009/09/18/a-shortage-of-technical-managers.aspx">A Shortage of Technical Managers</a>]
<ul>
<li>This just made me smile!</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/09/20/interesting-stuff-2009-09-20/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>C# Code coverage approaches and unit tests</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/09/14/code-coverage-approaches-with-tdd/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/09/14/code-coverage-approaches-with-tdd/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 03:15:15 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=442</guid>
		<description><![CDATA[This weekend I wrote a set of classes to [Determine and police password strength]. The interesting goal I set my self was to ensure that I got 100% code coverage using the MS unit test framework. Sounds easy! How hard can that be? Honestly I&#8217;ve focused more on TDD tests rather than code coverage. Well [...]]]></description>
			<content:encoded><![CDATA[<p>This weekend I wrote a set of classes to [<a href="/technicalblog/index.php/2009/09/13/better-way-to-determine-and-police-password-strengths/">Determine and police password strength</a>]. The interesting goal I set my self was to ensure that I got 100% code coverage using the MS unit test framework. Sounds easy! How hard can that be? Honestly I&#8217;ve focused more on TDD tests rather than code coverage.</p>
<p>Well firstly I have to say its not that easy <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> , secondarily it really shows the true benefit of [<a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a>] &#8211; more on that later. So on to the discoveries!</p>
<p>Being a TDD advocate I started off with an interface and then the tests before the code. So far so good &#8211; then on to the code. As a Spongebob episode would say &#8220;Several hours later&#8221; we were done. So crank up the tests and we are looking golden.</p>
<p>Unfortunately the code coverage wasn&#8217;t half as good as I had hoped for. So next couple of hours was spent updating the tests for coverage, and a number of edge cases surrounding the throwing of exceptions for invalid parameters. Interestingly a couple of areas that showed up outside of the TDD approach were certain areas in &#8220;for loops&#8221; where not executed because my test case was really unknowingly best case. The part that was revealing to me was that the TDD is really a &#8220;business&#8221; driven approach, code coverage is believed to be a programmers indicator of  &#8216;quality&#8217;. So while TDD (at least the first pass I end up doing) meets the business needs it is very hard to get 100% coverage from a business scenario.</p>
<p>Finally I got it up to 99.84% coverage. This last standout was VERY annoying, specifically looking at the code coverage everything was green &#8211; no red or yellow sections. Hrrrmm. Ok it was a simple function that has this 1 block of unexecuted code &#8211; a switch statement taking a enum in as a parameter.  So lets have a look have a look (note I&#8217;ve stripped a lot of the content and comments out for readability:</p>
<pre class="brush: csharp;">
   public enum PasswordStrengthIndex
   {
      None = 0,
      Weak = 1,
      Medium = 2,
      Strong = 3,
      MostStrong = 4,
   }

      public void ResetToDefinedPolicyStrength(PasswordStrengthIndex strength)
      {
         switch (strength)
         {
            case PasswordStrengthIndex.None:
               MinimumPasswordLength = 0;
               break;
            case PasswordStrengthIndex.Weak:
               MinimumPasswordLength = 4;
               break;
            case PasswordStrengthIndex.Medium:
               MinimumPasswordLength = 6;
               break;
            case PasswordStrengthIndex.Strong:
               MinimumPasswordLength = 8;
               break;
            case PasswordStrengthIndex.MostStrong:
               MinimumPasswordLength = 12;
               break;
         }
         return;
      }
</pre>
<p>The test case iterated through the enums and verified the output matched the expectations. Still I had this annoying block that was unexecuted. The next step was the Jimmy Neutron &#8220;Think Think Think&#8221;, a-ha! No default handler &#8211; so add one. Hmmm I cant add one that actually can be exercised as I&#8217;ve already used all my values in my enum. Well adding a default handler to anyone of those case statements still didnt resolve the issue. Now it was getting personal! I was dangerously close to calling in technical gurus and venting my disgust! So before making the calls time to search Google for &#8220;Code Coverage Switch&#8221; &#8211; and boy Google never ceases to amaze me.</p>
<p>Firstly it confirmed my suspicion that is was indeed the switch statement, second was a link that explained it in detail. Basically the default  handler was not getting called &#8211; and there were a number of &#8216;breaking&#8217; workarounds (change the enum to have another element to be used in the default case) in the Google answers, but one one that I &#8216;liked&#8217; the most was to force the cast (which I would link out to the original author out of respect but I cant find it now <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' />  ).</p>
<pre class="brush: csharp;">
      public void ResetToDefinedPolicyStrength(PasswordStrengthIndex strength)
      {
         switch (strength)
         {
            case PasswordStrengthIndex.None:
               MinimumPasswordLength = 0;
               break;
            case PasswordStrengthIndex.Weak:
               MinimumPasswordLength = 4;
               break;
            case PasswordStrengthIndex.Medium:
               MinimumPasswordLength = 6;
               break;
            case PasswordStrengthIndex.Strong:
               MinimumPasswordLength = 8;
               break;
            case PasswordStrengthIndex.MostStrong:
               MinimumPasswordLength = 12;
               break;
            default:
               throw new ArgumentException(&quot;Supplied strength is not recognized as enum&quot;, &quot;strength&quot;);
         }
         return;
      }

      [TestMethod()]
      [ExpectedException(typeof(ArgumentException))]
      public void ResetToDefinedPolicyStrengthBogus()
      {
         PasswordPolicy policy = new PasswordPolicy();
         policy.ResetToDefinedPolicyStrength(&lt;strong&gt;(PasswordStrengthIndex)666&lt;/strong&gt;);
      }
</pre>
<p>Look at the last line of the listing above. Use a cast to force the enum to be a number out side of the range it was looking for &#8211; ta da!  On a partially related note this reminds me of the fact Enums are definitely interesting beasts that can bite you if you have compiled against one then change its definition in a different assembly.</p>
<p>So now we have got to 100% code coverage &#8211; woo hoo! The realization (which is obvious and well know to many) is that without TDD you would most likely end up writing tests that cover your code &#8211; but miss the business requirements. So any programmers out there who think they have good code coverage but are not using TDD are likely to have a false believe in their code because the tool says 100% green (unless they are coding guru&#8217;s!) &#8211; they are only really testing what they have written and not the business requirements. On the flipside just writing TDD tests without coverage is highly unlikely to meet all the &#8216;code&#8217; edge cases (different than &#8216;business&#8217; edge cases). So the conclusion it that the blend of the two are the best, but yet still not perfect. You have to start with TDD, and then move to code coverage &#8211; business first, code second.</p>
<p>I&#8217;m hoping at some point management teams will start to understand that even with 100% executed code coverage there can still be bugs as its a data world we live in! Obviously I&#8217;m an optimist!</p>
<p>Gareth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/09/14/code-coverage-approaches-with-tdd/feed/</wfw:commentRss>
		<slash:comments>3</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>SQLite 3.6.18 has been offically released!</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/09/11/sqlite-3-6-18-has-been-offically-released/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/09/11/sqlite-3-6-18-has-been-offically-released/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 16:07:35 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=431</guid>
		<description><![CDATA[There are a number of good changes here! Improved query planner: Through better use of statistics Compile time option enables Analyze to better handle the index histograms Additionally it was just plain improved as well! Recursive triggers Delete triggers fire during a REPLACE/MERGE More precise use of caching approaches with the Shared Cache &#8211; basically [...]]]></description>
			<content:encoded><![CDATA[<p>There are a number of good changes here!</p>
<ul>
<li>Improved query planner:
<ul>
<li>Through better use of statistics</li>
<li>Compile time option enables Analyze to better handle the index histograms</li>
<li>Additionally it was just plain improved as well!</li>
</ul>
</li>
<li>Recursive triggers</li>
<li>Delete triggers fire during a REPLACE/MERGE</li>
<li>More precise use of caching approaches with the
<ul>
<li>Shared Cache &#8211; basically cache the results within the application rather can on each thread. Now configurable on a per-thread basis rather than global.</li>
<li>Private &#8211; The old way</li>
</ul>
</li>
</ul>
<p>Well done to the SQLite team! Good stuff</p>
<p>More details can be found [<a href="http://www.sqlite.org/releaselog/3_6_18.html">SQLite Release 3.6.18 On 2009 Sep 11 (3.6.18)</a>]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/09/11/sqlite-3-6-18-has-been-offically-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interesting Cloud developments, and other technical news</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/09/01/interesting-cloud-developments-and-other-technical-news/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/09/01/interesting-cloud-developments-and-other-technical-news/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 03:16:59 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[High Availability]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=427</guid>
		<description><![CDATA[It seems with the VMWare conference that the relative quiet has brought out the virtualization fairy&#8217;s out to play! What a difference a week makes. All of a sudden we get: VMware announces VMware vCloud Express, goes head to head with Amazon EC2 VMware today announced vCloud Express, a new class of service that will [...]]]></description>
			<content:encoded><![CDATA[<p>It seems with the VMWare conference that the relative quiet has brought out the virtualization fairy&#8217;s out to play! What a difference a week makes. All of a sudden we get:</p>
<ul>
<li><a href="http://virtualization.com/news/2009/09/01/vmware-announces-vmware-vcloud-express-goes-head-to-head-with-amazon-ec2/">VMware announces VMware vCloud Express, goes head to head with Amazon EC2</a>
<ul>
<li>VMware today announced vCloud Express, a new class of service that will deliver on-demand, pay-as-you-go computing power as a service, much like Amazon Web Services’ Elastic Compute Cloud (EC2).</li>
</ul>
</li>
<li><a href="http://www.datacenterknowledge.com/archives/2009/08/19/a-pci-compliant-cloud-not-at-amazon/">A PCI-Compliant Cloud? Not at Amazon</a>
<ul>
<li>Very interesting debate and conclusion regarding Amazon EC2 &amp; PCI. Worth a read!</li>
</ul>
</li>
<li><a href="http://blogs.msdn.com/usisvde/archive/2009/08/29/azure-reference-architecture-explored-with-project-riviera.aspx">Azure Reference Architecture Explored with Project Riviera </a>
<ul>
<li>If you’ve been wanting to see how a multi-tenant architecture works with Windows Azure Platform, you’ll want to see Project Riviera. The project has been released on MSDN and includes source code. Interestingly the sample application is a loyalty application!</li>
</ul>
</li>
<li><a href="http://cloudsecurity.org/2009/08/31/cloud-cartography-side-channel-attacks/">Cloud Cartography &amp; Side Channel Attacks</a>
<ul>
<li>This is obviously dependent on the availability of a weakness in the hypervisor, but definitely an interesting concept none the less.</li>
</ul>
</li>
</ul>
<p><span style="text-decoration: underline;"><strong>Security</strong></span></p>
<ul>
<li><a href="http://www.securitytracker.com/alerts/2009/Aug/1022792.html">Microsoft Internet Information Server (IIS) FTP Server Buffer Overflow Lets Remote Authenticated Users Execute Arbitrary Code</a>
<ul>
<li>Any one running IIS 5, 5.1, or 6 and FTP &#8211; watch out!</li>
</ul>
</li>
<li><a href="http://www.net-security.org/secworld.php?id=7949">New version of WiKID authentication server</a>
<ul>
<li>WiKID Systems announced version 3.4 of the WiKID Strong Authentication Server in Enterprise and Community Editions. New features include built-in support for the SAML Single Sign-On Service for Google Apps, a new self-registration process for Active Directory users and extended vendor-specific RADIUS attributes.</li>
<li>Pretty interesting stuff, not seen this before.</li>
</ul>
</li>
</ul>
<p>Hopefully my writers block has been solved and I&#8217;ll get back to writing some code <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Gareth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/09/01/interesting-cloud-developments-and-other-technical-news/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Azure Invitation has arrived!</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/08/24/sql-azure-is-available-to-me/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/08/24/sql-azure-is-available-to-me/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 01:13:11 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[High Availability]]></category>
		<category><![CDATA[SQLServer]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=423</guid>
		<description><![CDATA[Well I&#8217;m finally on the Azure CTP servers! If anyone has been hiding in a cave Azure is the Microsoft play at getting Microsoft SQL Server into the cloud. After creating an account you can create and drop databases in the &#8216;cloud&#8217;. Definitely pretty cool stuff. Now to see how well it performs and verify [...]]]></description>
			<content:encoded><![CDATA[<p>Well I&#8217;m finally on the Azure CTP servers! If anyone has been hiding in a cave Azure is the Microsoft play at getting Microsoft SQL Server into the cloud. After creating an account you can create and drop databases in the &#8216;cloud&#8217;.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-424" title="Azure Database Management Screen" src="http://www.csharphacker.com/technicalblog/wp-content/uploads/2009/08/AzureDatabase.jpg" alt="Azure Database Management Screen" width="468" height="349" /></p>
<p style="text-align: left;">Definitely pretty cool stuff. Now to see how well it performs and verify it supports all the nice SQ L stuff  (sparse columns, PIVOT, stored procedures etc).</p>
<p style="text-align: left;">This will certainly be hyped by Microsoft over the coming weeks, and we will be trying it out! Much more to come on this topic,</p>
<p style="text-align: left;">
<p style="text-align: left;">Gareth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/08/24/sql-azure-is-available-to-me/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>We all wanted the reason why we wanted to install Win 7 &#8211; right?</title>
		<link>http://www.csharphacker.com/technicalblog/index.php/2009/08/04/win-7-booting-to-vhd/</link>
		<comments>http://www.csharphacker.com/technicalblog/index.php/2009/08/04/win-7-booting-to-vhd/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 05:29:28 +0000</pubDate>
		<dc:creator>Gareth</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.csharphacker.com/technicalblog/?p=420</guid>
		<description><![CDATA[Ok I admit I&#8217;ve been watching the clock tick closer to August 6th , but if you work with virtual machines (and you know who you are!) and have been ever frustrated by speed or it just not feeling normal then just check out the boot to VHD feature!: [The Virtualization Nation Podcast – Episode [...]]]></description>
			<content:encoded><![CDATA[<p>Ok I admit I&#8217;ve been watching the clock tick closer to August 6th <img src='http://www.csharphacker.com/technicalblog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> , but if you work with virtual machines (and you know who you are!) and have been ever frustrated by speed or it just not feeling normal then just check out the boot to VHD feature!:</p>
<ul>
<li>[<a href="http://blogs.msdn.com/mikekol/archive/2009/05/14/the-virtualization-nation-podcast-episode-3-want-to-boot-a-physical-computer-from-a-vhd.aspx">The Virtualization Nation Podcast – Episode 3: Want to boot a physical computer from a VHD?</a>]</li>
<li>[<a href="http://www.hanselman.com/blog/StepByStepTurningAWindows7DVDOrISOIntoABootableVHDVirtualMachine.aspx">Step-By-Step: Turning a Windows 7 DVD or ISO into a Bootable VHD Virtual Machine</a>]</li>
</ul>
<p>Seriously cool &#8211; I mean seriously! Native booting to a VHD on your disk &#8211; I want to buy who ever thought of that and got management to agree to putting that into Windows 7 (think HyperVisor) a beer!</p>
<p>I LOVE IT!!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphacker.com/technicalblog/index.php/2009/08/04/win-7-booting-to-vhd/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>
	</channel>
</rss>
