<?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>Virtual Memory</title>
	<atom:link href="http://blog.brianshotola.com/index.php/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.brianshotola.com</link>
	<description>An extention of my brain.</description>
	<lastBuildDate>Fri, 14 May 2010 13:04:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Get Localized Month Names in .NET</title>
		<link>http://blog.brianshotola.com/index.php/2010/05/14/get-localized-month-names-in-net</link>
		<comments>http://blog.brianshotola.com/index.php/2010/05/14/get-localized-month-names-in-net#comments</comments>
		<pubDate>Fri, 14 May 2010 13:04:49 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[localization]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[months]]></category>

		<guid isPermaLink="false">http://blog.brianshotola.com/?p=224</guid>
		<description><![CDATA[[Test] public void Junk() { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo(&#8220;da-DK&#8221;); string[] localizedMonths = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.MonthNames; string[] invariantMonths = System.Globalization.DateTimeFormatInfo.InvariantInfo.MonthNames; System.Console.Out.WriteLine(&#8220;Current Culture is &#8221; + System.Globalization.CultureInfo.CurrentCulture.EnglishName); for (int month = 0; month &#60; 12; month++) { System.Console.Out.WriteLine(localizedMonths[month]); System.Console.Out.WriteLine(invariantMonths[month]); } }]]></description>
			<content:encoded><![CDATA[<p>[Test]<br />
public void Junk()<br />
{<br />
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo(&#8220;da-DK&#8221;);</p>
<p>string[] localizedMonths = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.MonthNames;<br />
string[] invariantMonths = System.Globalization.DateTimeFormatInfo.InvariantInfo.MonthNames;</p>
<p>System.Console.Out.WriteLine(&#8220;Current Culture is &#8221; + System.Globalization.CultureInfo.CurrentCulture.EnglishName);<br />
for (int month = 0; month &lt; 12; month++)<br />
{<br />
System.Console.Out.WriteLine(localizedMonths[month]);<br />
System.Console.Out.WriteLine(invariantMonths[month]);<br />
}</p>
<p>}</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianshotola.com/index.php/2010/05/14/get-localized-month-names-in-net/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rhino Mocks Callbacks</title>
		<link>http://blog.brianshotola.com/index.php/2010/04/15/rhino-mocks-callbacks</link>
		<comments>http://blog.brianshotola.com/index.php/2010/04/15/rhino-mocks-callbacks#comments</comments>
		<pubDate>Thu, 15 Apr 2010 19:19:23 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[mocking]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[rhino]]></category>
		<category><![CDATA[rhinomocks]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[unittest]]></category>
		<category><![CDATA[unittesting]]></category>

		<guid isPermaLink="false">http://blog.brianshotola.com/?p=216</guid>
		<description><![CDATA[Rhino Mocks Callbacks are what I have been trying to find for 2 days! My problem is that I needed to test the internals of a method by checking to see that a value had been evaluated properly.  The result of this operation gets passed to my DAL to be inserted into my DB.  My [...]]]></description>
			<content:encoded><![CDATA[<p>Rhino Mocks Callbacks are what I have been trying to find for 2 days!</p>
<p>My problem is that I needed to test the internals of a method by checking to see that a value had been evaluated properly.  The result of this operation gets passed to my DAL to be inserted into my DB.  My test was to test my Business Layer so I needed to mock the DAL to prevent the DB hit from occurring.  The problem was, how could I grab the value from inside my BL method?</p>
<p>With Rhino Mocks, I mocked my DAL and recoreded an Expect on the method that does the DB insert.  Now all I needed to do was to replace the default implementation of my DAL method with one used for testing.  The internals of the testing method would be able to read the params being passed to the DAL from the BL, thus allowing me to verify that the BL evaluated what it was supposed to properly before passing the data on to be inserted.</p>
<p>Rhino Mocks Callbacks to the rescue!  I love the power of delegates, unfortunately it&#8217;s still the largest concept that repeatedly trips me up.  After locating <a href="http://mikehadlow.blogspot.com/2007/12/rhino-mocks-callbacks-with-lambda.html" target="_blank">this post </a>on using Rhino Mocks Callbacks, I was finally able to accomplish my goal.</p>
<p>The application in the example below is a WCF service which accepts TFS Notification messages when a WorkItem changes.  When I recieve the notification from TFS, I am logging the message in a log table.  One of the params that is sent from TFS contains the publisher&#8217;s url in an XML string.  My BL needs to select the value of the attribute containing this url and insert it into a column in my table.  Thus, what I wanted to test was that my xpath is correct (and if TFS changes something in subsequent versions I&#8217;ll know immediately that they changed an expected format).</p>
<h3>WCF Method to receive the TFS notification:</h3>
<pre>public void Notify(string eventXml, string tfsIdentityXml, SubscriptionInfo subscriptionInfo)
        {
            XmlDocument eventXmlDoc = new XmlDocument();
            XmlDocument tfsIdentityXmlDoc = new XmlDocument();
            try
            {
                eventXmlDoc.LoadXml(eventXml);
                tfsIdentityXmlDoc.LoadXml(tfsIdentityXml);
                TfsNotificationDto tfsNotificationDto = new TfsNotificationDto
                    {
                        Message = eventXml,
                        Date = DateTime.Now,
                        Publisher = tfsIdentityXmlDoc.SelectSingleNode("TeamFoundationServer").Attributes["url"].Value,
                        Subscriber = "",
                        Success = 'F'
                    };
                this._repo.LogTfsNotification(tfsNotificationDto);               
            }
            catch (Exception)
            {
                throw;
            }            
        }</pre>
<h3>Test method utilizing Rhino Mocks to mock the DAL:</h3>
<pre>[Test]
        public void TestLogTfsNotification()
        {
            string pub = string.Empty;
            With.Mocks(delegate
            {
                IRepository repo = Mocker.Current.StrictMock&lt;IRepository&gt;();
                TfsNotificationDto tfsNotificationDto = RepositoryTests.MockTfsNotificationDto;
                Expect.Call(() =&gt; repo.LogTfsNotification(tfsNotificationDto)).Callback(new Delegates.Function&lt;bool, TfsNotificationDto&gt;(notification =&gt; { pub = notification.Publisher; return true;}));
                Mocker.Current.ReplayAll();
                ITfsEventService service = new TfsEventService(repo);
                service.Notify(eventXml, tfsIdentityXml, subscriptionInfo);
            });           
            Assert.AreEqual(this.publisher, pub);
        }</pre>
<p>What I can now do is in the LogTfsNotification method of the mocked repo, I can now read the parameter passed to it from the service.Notify method.  Service.Notify is extracting the subscriber url and packages it up into a TfsNoficationDto that is passed to LogTfsNotification.  Thus I can do notification.Publisher to see what value was extracted from the xml in the service object of my BL.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianshotola.com/index.php/2010/04/15/rhino-mocks-callbacks/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why it&#8217;s Not a Good Idea to Use Incrementing Integer Values as Primary Keys</title>
		<link>http://blog.brianshotola.com/index.php/2010/04/13/why-its-not-a-good-idea-to-use-incrementing-integer-values-as-primary-keys</link>
		<comments>http://blog.brianshotola.com/index.php/2010/04/13/why-its-not-a-good-idea-to-use-incrementing-integer-values-as-primary-keys#comments</comments>
		<pubDate>Tue, 13 Apr 2010 23:11:30 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Q&A]]></category>
		<category><![CDATA[sqlserver]]></category>
		<category><![CDATA[sybase]]></category>

		<guid isPermaLink="false">http://blog.brianshotola.com/?p=203</guid>
		<description><![CDATA[This question was posed to me by a co-worker at my client after expressing my dislike of using incrementing Integer values for surregate record keys (primary keys) in a relational database.  This response is simply my opinion and based on my experience.  If you disagree or have feedback, please leave a comment. Question: &#8230;I’m curious [...]]]></description>
			<content:encoded><![CDATA[<p>This question was posed to me by a co-worker at my client after expressing my dislike of using incrementing Integer values for surregate record keys (primary keys) in a relational database.  This response is simply my opinion and based on my experience.  If you disagree or have feedback, please leave a comment.</p>
<h2>Question:</h2>
<p>&#8230;I’m curious about your aversion to INT’s (and I assume by extension Identities).  My, totally unscientific, experience has been that those who use SQLServer are quite fervent about using GUIDs but coming from the Sybase world where the option doesn’t exist, I’ve never seen the benefit.  I briefly had to maintain a MSSql backed system with GUIDs and it was infuriating to me, as a developer, to deal with them.  Looking in the database was utterly useless because of all these 32 character IDs.</p>
<h2>Answer:</h2>
<h3>Example 1:</h3>
<p>Let’s say that you use incrementing INTs for IDs on a table.  This particular table collects messages in a log for example.  In production we are capturing notifications and logging them into our table.  Ooops.  Something went wrong.  Now a developer would like to execute his code against the messages that came in last night.  So we will want to copy a subset of production records into development for inspection.  The development table already has records in it with the same IDs as those records in production.  All IDs need to stay the way they are.  How can we import these production records into dev with ID conflicts?</p>
<p>Why might we not want to or be able to change these IDs?  As my co-worker mentioned, who posed the initial question, foreign keys are a great reason why you might not be able to change the keys.  There are other practical reasons too, like traceability, making sure you know what record in production is the record you are working with in development in this scenario.</p>
<h3>Example 2:</h3>
<p>We are using auto incrementing INTs in our application.  We have started the incrementing at 0 and have gone up from there.  Some smart young developer says, I need to add a branch in this here logic when a particular record comes through my code.  So this young go-getter decides to enter a magic record into a table with an ID of -1.  And being the slick young chap that he is, he adds an “if(record.id &lt; 0){do my stuff}”.  Seems harmless enough, right?  However, now IDs have meaning.  A mathematical operation has just been applied to an ID.  IDs are not supposed to represent mathematical values, they simply hold a unique reference to a record.  So if someone happens to look at the DB and say “hey, how’d that record get in there?” and blow it away, you will have issues.</p>
<h2>The Real World</h2>
<p>Here’s my actual real-world scenario.  A company has inherited Sybase databases in an acquisition (Sybase doesn&#8217;t have a uniqueID data type).  They were storing item IDs as incrementing INTs.  They process so many items, that they realized that they were going to run out of space in code.  What they wanted me to do was convert from INT to LONG.  While this would have alleviated the problem, all you’re doing is setting a new cap to be hit later.  So myself and another consultant proposed we switch to GUIDs so there would never be a cap (note as in Example 1, they also had a need to bring production data into dev for testing) and never be record conflicts moving from environment to environment.  When we finally got the OK to do so, we hit a snag.  There were tons of magic IDs in the code with mathematical operations being applied.  In code, this change involved a change from INT values to Strings.  While a large effort, it was a manageable one.  That is until we found a ton of magic ID values (as in Example 2).  This effort now involved figuring out what the magic strings were and would involve looking up the data behind it since mathematical operations can’t be applied to GUIDs.  Nevertheless, at the time, said company was too busy with new development to tackle this process since myself and my co-worker didn’t have the domain knowledge necessary to make these changes.  It essentially required a developer from the former merged company to untangle the mess.  Ultimately I don’t know what became of it, but I do know that they were not able to use less expensive contract resources to perform what should have been a rather trivial task.</p>
<p>I will admit, looking at GUIDs isn&#8217;t the most human-friendly of data types/formats.  However, IDs are supposed to be that, just IDs.  Social Security Numbers aren&#8217;t the most human-friendly format either, but we learn to live with it.  Regardless, we use IDs in the context of a relational DB, so with a couple extra keys strokes, you can pull back any data you need to along with your select to give the GUID value the proper meaning you require.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianshotola.com/index.php/2010/04/13/why-its-not-a-good-idea-to-use-incrementing-integer-values-as-primary-keys/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Scrum Late Fees Rule!</title>
		<link>http://blog.brianshotola.com/index.php/2010/02/05/scrum-late-fees-rule</link>
		<comments>http://blog.brianshotola.com/index.php/2010/02/05/scrum-late-fees-rule#comments</comments>
		<pubDate>Fri, 05 Feb 2010 15:18:42 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[scrum]]></category>

		<guid isPermaLink="false">http://blog.brianshotola.com/index.php/2010/02/05/scrum-late-fees-rule</guid>
		<description><![CDATA[Mmmmm]]></description>
			<content:encoded><![CDATA[<p><img style="display:block;margin-right:auto;margin-left:auto;" alt="image" src="http://blog.brianshotola.com/wp-content/uploads/2010/02/wpid-2010-02-05-08.59.28.jpg" /></p>
<p>Mmmmm</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianshotola.com/index.php/2010/02/05/scrum-late-fees-rule/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu Networking</title>
		<link>http://blog.brianshotola.com/index.php/2010/02/01/ubuntu-networking</link>
		<comments>http://blog.brianshotola.com/index.php/2010/02/01/ubuntu-networking#comments</comments>
		<pubDate>Mon, 01 Feb 2010 22:37:52 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.brianshotola.com/?p=190</guid>
		<description><![CDATA[The other day I went to my company&#8217;s office and tried to browse and kept getting denied on DNS lookups. Our network guru told me I needed to add a line in resolve.conf to find the nameserver. /etc/resolve.conf Add  line: nameserver 192.168.1.31 The problem though was that this file gets overwritten, so I had to [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I went to my company&#8217;s office and tried to browse and kept getting denied on DNS lookups. Our network guru told me I needed to add a line in resolve.conf to find the nameserver.</p>
<pre>/etc/resolve.conf</pre>
<p>Add  line:</p>
<pre>nameserver 192.168.1.31</pre>
<p>The problem though was that this file gets overwritten, so I had to ask him again for the setting today.  Frustrated at this, I did a bit of research and it looks like if I want to make this change permanent I need to modify dhclient.conf (http://ubuntuforums.org/showthread.php?t=445753)</p>
<pre>/etc/dhcp3/dhclient.conf</pre>
<p>Add:</p>
<pre>supersede domain-name "company.com";
prepend domain-name-servers 192.168.1.31;</pre>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 193px; width: 1px; height: 1px;">http://ubuntuforums.org/showthread.php?t=445753</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianshotola.com/index.php/2010/02/01/ubuntu-networking/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Move a Directory in TFS Source Control</title>
		<link>http://blog.brianshotola.com/index.php/2010/01/26/move-a-directory-in-tfs-source-control</link>
		<comments>http://blog.brianshotola.com/index.php/2010/01/26/move-a-directory-in-tfs-source-control#comments</comments>
		<pubDate>Tue, 26 Jan 2010 22:17:37 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[TFS]]></category>

		<guid isPermaLink="false">http://blog.brianshotola.com/?p=183</guid>
		<description><![CDATA[tf rename C:\Projects\App\Project\Trunk C:\Projects\CIBMTR\App\Project\NewDir\Trunk /login:username,password]]></description>
			<content:encoded><![CDATA[<pre>tf rename C:\Projects\App\Project\Trunk C:\Projects\CIBMTR\App\Project\NewDir\Trunk /login:username,password</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianshotola.com/index.php/2010/01/26/move-a-directory-in-tfs-source-control/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Make an executable script file in Ubuntu</title>
		<link>http://blog.brianshotola.com/index.php/2010/01/25/make-an-executable-script-file-in-ubuntu</link>
		<comments>http://blog.brianshotola.com/index.php/2010/01/25/make-an-executable-script-file-in-ubuntu#comments</comments>
		<pubDate>Mon, 25 Jan 2010 15:53:39 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[permissions]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.brianshotola.com/?p=181</guid>
		<description><![CDATA[Create a new file with some script in it. sudo chmod u+x filename sudo chown user:group filename]]></description>
			<content:encoded><![CDATA[<p>Create a new file with some script in it.</p>
<pre>sudo chmod u+x filename</pre>
<pre>sudo chown user:group filename</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianshotola.com/index.php/2010/01/25/make-an-executable-script-file-in-ubuntu/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modifying PATH variable in Ubuntu</title>
		<link>http://blog.brianshotola.com/index.php/2010/01/25/modifying-path-variable-in-ubuntu</link>
		<comments>http://blog.brianshotola.com/index.php/2010/01/25/modifying-path-variable-in-ubuntu#comments</comments>
		<pubDate>Mon, 25 Jan 2010 15:48:30 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[environment]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.brianshotola.com/?p=179</guid>
		<description><![CDATA[sudo gedit ~/.bashrc Add this line to the file (or modify if the file already has an entry for PATH): PATH=[your path]:”${PATH}” Save the file Execute to refresh the file without logging out: source .bashrc]]></description>
			<content:encoded><![CDATA[<pre>sudo gedit ~/.bashrc</pre>
<p>Add this line to the file (or modify if the file already has an entry for PATH):</p>
<pre>PATH=[your path]:”${PATH}”</pre>
<p>Save the file</p>
<p>Execute to refresh the file without logging out:</p>
<pre>source .bashrc</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianshotola.com/index.php/2010/01/25/modifying-path-variable-in-ubuntu/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET RSA Encryption Class</title>
		<link>http://blog.brianshotola.com/index.php/2010/01/22/net-rsa-encryption-class</link>
		<comments>http://blog.brianshotola.com/index.php/2010/01/22/net-rsa-encryption-class#comments</comments>
		<pubDate>Fri, 22 Jan 2010 17:49:16 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[encryption]]></category>
		<category><![CDATA[rsa]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://blog.brianshotola.com/?p=174</guid>
		<description><![CDATA[The following class is the class I created to RSA encrypt database passwords.  The implementation is a case study of need for this at a former client. using System; using System.Collections.Generic; using System.Text; using System.Security.Cryptography; using System.IO; using System.Xml; namespace Utility { public class RSAEncryption { private XmlDocument publicKey = null; private XmlDocument privateKey = [...]]]></description>
			<content:encoded><![CDATA[<p>The following class is the class I created to RSA encrypt database passwords.  The implementation is a case study of need for this at a former client.</p>
<pre>using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Xml;

namespace Utility
{
 public class RSAEncryption
 {
 private XmlDocument publicKey = null;
 private XmlDocument privateKey = null;
 private System.Security.Cryptography.RSACryptoServiceProvider rsa;

 public RSAEncryption(XmlDocument publicKey) : this(publicKey, null)
 {
 ;
 }

 public RSAEncryption(XmlDocument publicKey, XmlDocument privateKey)
 {
 this.publicKey = publicKey;
 this.privateKey = privateKey;
 RSACryptoServiceProvider.UseMachineKeyStore = true;
 this.rsa = new RSACryptoServiceProvider();            
 }

 public string EncryptData(string data2Encrypt)
 {
 byte[] cipherbytes = null;
 try
 {
 rsa.FromXmlString(this.publicKey.OuterXml);
 byte[] plainbytes = System.Text.Encoding.UTF8.GetBytes(data2Encrypt);
 cipherbytes = rsa.Encrypt(plainbytes, false);
 }
 catch (Exception ex)
 {
 Logger.LogException(ex, this);
 throw ex;
 }
 return Convert.ToBase64String(cipherbytes);
 }

 public string DecryptData(string data2Decrypt)
 {
 byte[] plain = null;
 try
 {
 byte[] getpassword = Convert.FromBase64String(data2Decrypt);
 rsa.FromXmlString(this.privateKey.OuterXml);
 plain = rsa.Decrypt(getpassword, false);
 }
 catch (Exception ex)
 {
 Logger.LogException(ex, this);
 throw ex;
 }
 return System.Text.Encoding.UTF8.GetString(plain);
 }

 public static void CreateNewKeys(string publicKeyPath, string privateKeyPath)
 {
 try
 {
 Logger.LogInfo("Creating new keys", new object());
 Logger.LogInfo("Creating RSA Crypto Service Provider", new object());
 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

 Logger.LogInfo(string.Format("Deleting private key: {0}", privateKeyPath), new object());
 if (File.Exists(privateKeyPath)) File.Delete(privateKeyPath);
 XmlDocument publicPrivateKeyXML = new XmlDocument();
 publicPrivateKeyXML.LoadXml(rsa.ToXmlString(true));
 Logger.LogInfo(string.Format("Creating private key: {0}", privateKeyPath), new object());
 publicPrivateKeyXML.Save(privateKeyPath);

 Logger.LogInfo(String.Format("Deleting public key: {0}", publicKeyPath), new object());
 if (File.Exists(publicKeyPath)) File.Delete(publicKeyPath);
 XmlDocument publicOnlyKeyXML = new XmlDocument();
 publicOnlyKeyXML.LoadXml(rsa.ToXmlString(false));
 Logger.LogInfo(String.Format("Creating public key: {0}", publicKeyPath), new object());
 publicOnlyKeyXML.Save(publicKeyPath);
 }
 catch (Exception ex)
 {
 Logger.LogException(ex, new object());
 throw ex;
 }
 }
 }
}</pre>
<p>This class is designed to use public &amp; private key pairs that are stored on a file system in xml using RSA encryption.  The production implementation of this is for decrypting database passwords at runtime in a web application.  My database connection strings are stored in the web.config for the application and the passwords are embedded in these connection strings.  Normally these passwords could be stored in clear on the server since no one other than the administrator can access the box.  However, this thought fell apart once we put in an application to schedule releases.  This application allowed us to schedule when a release was happening, what date, who it affects, etc.  The other thing the application allowed for was the attachment of the change to go into production.  This application release schedule is an internal application and since all the code is compiled, placing the code changes in this list was great for our needs because it tied the code change directly to the request so that if we had a historical question about anything we could always look back in the application release schedule.</p>
<p>The one problem with this though had to do with the connection strings.  In many cases the release would cause a change to the web.config.  Since this web.config has production database passwords, we didn&#8217;t want to attach it to the request in clear, as it was the one glaring item that someone who wished to be malicious could do something with.  So our solution was to encrypt the password.  We could have encrypted the whole connection string, but personally I like to be able to see information about the connection in clear as it makes for easier debugging in my opinion.  Plus, if the user doesn&#8217;t have the password they can&#8217;t do too much with the other information.</p>
<p>Thus was born the class listing above.  This class is a generic RSA Encryption class that can generate a new public/private key pair to xml stored on the file system and can encrypt and decrypt from keys passed to it retrieved from the file system (or anywhere else for that matter).  I chose to use RSA encryption for a couple of reasons.  One is that since the password is stored and retrieved from the web.config, a one way hash wouldn&#8217;t do much for us.  I could have used a symmetric key algorithm, but then all of the developers would have to have access to the one key that would encrypt and decrypt the password.  RSA, or any asymmetric algorithm, allowed me to give the developers a key to encrypt with while protecting the one key that can decrypt.</p>
<p>I keep referring to the keys being stored on the file system because the production implementation works like this&#8230;</p>
<p>We generate the public/private key pair to be used in production.  One trusted developer or an admin has permissions to do this (I created a utility to generate the key/pairs so a non-programmer can be assigned the task of managing the keys).  Once the keys are generated, the public key is stored in source control.  This way all the developers have access to the public key for encrypting passwords to go into a connection string.  The admin then takes the private key and installs it to a secure directory on the server that the application user account has access to.  So at this point, the public key is&#8230;erm&#8230;public, and the private key is secured so that only the server admin and the application user have access.  What this does is minimize who can decrypt a password.  Sure anyone could encrypt and insert a new password and that password would be decryped properly at runtime, it&#8217;s pretty much useless unless that change has been done on the database as well.  In the scenario presented in this post, one developer will have permissions to modify the database password, thus this individual is responsible for encrypting the password.  With this policy in place, no one other than this point person knows the production db password, and that&#8217;s the way I want it.  Getting back to the decryption part, we have stored the private key in a secure directory that the application user has access to.  At runtime, when the database connection is created, the application is configured to pull the private key from this secure directory, pass it into the above listed class so that the decrypt method can be called.  Since all of this is happening in memory, there should be no easy way for an attacker to view the password in clear.</p>
<p>As for how this works in development, the developer can pretty much do whatever he wants regarding this.  The data access layer can still work just fine with non-encrypted strings, so in development the programmer can enter whatever the password is for his local database.  The encryption utility is also stored in source control so any developer can create his own custom keys and use those to encrypt/decrypt in his local environment.  Everyone just needs to be sure that the production config always go out the door with its password encrypted using the production public key.</p>
<p>For more information on RSA Encryption in .NET, here are some good references:</p>
<p><a title=".NET Encryption Simplified" href="http://www.codeproject.com/KB/security/SimpleEncryption.aspx" target="_blank">http://www.codeproject.com/KB/security/SimpleEncryption.aspx</a></p>
<p><a title="RSA Encryption in .NET -- Demystified!" href="http://www.eggheadcafe.com/articles/20020630.asp" target="_blank">http://www.eggheadcafe.com/articles/20020630.asp</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianshotola.com/index.php/2010/01/22/net-rsa-encryption-class/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Regular Expression for Locating a Password in a Connection String</title>
		<link>http://blog.brianshotola.com/index.php/2010/01/19/regular-expression-for-locating-a-password-in-a-connection-string</link>
		<comments>http://blog.brianshotola.com/index.php/2010/01/19/regular-expression-for-locating-a-password-in-a-connection-string#comments</comments>
		<pubDate>Tue, 19 Jan 2010 21:10:33 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[regular expressions]]></category>

		<guid isPermaLink="false">http://blog.brianshotola.com/?p=156</guid>
		<description><![CDATA[I used this RegEx to locate an encrypted password in a connection string. I wrote a utility that would allow for the encryption of a password string so that the clear text password could be replaced by the encrypted string in the config. I did this because I didn&#8217;t want the whole string encrypted, just [...]]]></description>
			<content:encoded><![CDATA[<p>I used this RegEx to locate an encrypted password in a connection string. I wrote a utility that would allow for the encryption of a password string so that the clear text password could be replaced by the encrypted string in the config. I did this because I didn&#8217;t want the whole string encrypted, just the password. Thus at runtime the logic needed to retrieve the connection string from the config, find the password value and run it through the decryption algorithm. This is the explanation for the RegEx I used to accomplish this.</p>
<pre>string passwordGroup = "pwd";
string searchExpression = "(?i)password=(?&lt;" + passwordGroup + @"&gt;[0-9a-zA-Z\+/=]+)";</pre>
<p>Example strings that this expression will be run against are :</p>
<pre>&lt;add name="AConnectionString" connectionString="Provider=OraOLEDB.Oracle;Data Source=XE; User ID=uid0; Password=AcQtF5W9CGmph8NxtPVfyPnDBxrmHU=;OLEDB.NET=true;Unicode=True" /&gt;</pre>
<pre>&lt;add name="DBConnName" connectionString="packet size=4096;user id=uid0;data source=SERVER01;persist security info=True;initial catalog=catalogName;password=IkX+129i/iUshSJc0O3rCxHKz2lv6+mRNe91vIw=" /&gt;</pre>
<p><strong><em>(?i)</em> </strong>- This is a modifier affecting how the remainder of the string is processed.</p>
<p><strong><em>(?</em></strong><em><strong>x)</strong> </em>- this syntax indicates that this is a modifier.  The <em>x</em> will be replaced with an appropriate set of modifiers.  In my case those are i, s, &amp; m.</p>
<p><strong>i </strong><em>- </em>turns on case insensitivity for the remainder of the string.</p>
<p><strong><em>password=</em> </strong>- Represents a literal string. I am using this string to find the position at which to start the regex match for the password value I am searching for.  In this case the expression will begin matching at the p in password.</p>
<p><em><strong>(?&lt;&#8221; + passwordGroup + @&#8221;&gt;[0-9a-zA-Z\+/=]+) </strong>-</em> boils down to (?&lt;pwd&gt;[0-9a-zA-Z\+/=]+).  Let&#8217;s take a look at the first part of this expression:</p>
<p><strong>(?&lt;&gt;) </strong>- This is the .NET syntax for creating a named group.  Groups are organizational structures used to pluck particular search strings out of a larger string.  By default regex engines will sequentially number the groups starting at 0. In my case, I want to give my group a specific name for retrieval from the match, thus this syntax.  In my expression the &#8220;pwd&#8221; string represents the name for my matching group.  The contents of the matched group will be the string returned by the evaluation of the expression inside the parenthesis.</p>
<p><em><strong>[0-9a-zA-Z\+/=]+</strong> </em>- matches any string containing alphanumeric characters as well as matching on +, /, and =.  These 3 extra characters are allowed in the set of characters the encrypted string may contain.  As you can see both examples show that the password field will either end with a &#8221; or a ;.  Since neither of those two terminating characters are in the set of allowed characters, the match will end there.  Thus the match will start at the &#8220;p&#8221; in password and end before either the ; or the &#8221; at the end of the password value.</p>
<p>This expression will return an entire match of: password=value.  From this match one group will exist which will contain only the password value.</p>
<p>My entire method using this expression and extracting the named group:</p>
<pre>protected string RetrievePasswordValue(string connectionString)
 {
 string passwordGroup = "pwd";
 string searchExpression = "(?i)password=(?&lt;" + passwordGroup + @"&gt;[0-9a-zA-Z\+/=]+)";

 try
 {
 Match passwordMatch = Regex.Match(connectionString, searchExpression);                
 return passwordMatch.Groups[passwordGroup].Value;
 }
 catch (Exception ex)
 {
 // Do something better than this exception handling, obviously
 throw ex;
 }            
 }
 }</pre>
<p>I&#8217;m no regex expert by any means, so there may be better ways to write the expression. Please leave a comment if you see a glaring problem with my expression. One thing I could probably do to it would be to add a more explicit terminator on &#8221; or ; rather than have it end by just not being in the set of valid characters.</p>
<p>Here are some great links for learning and testing your regular expressions:</p>
<p><a title="Regular-Expressions.info" href="http://www.regular-expressions.info" target="_blank">http://www.regular-expressions.info</a></p>
<p><a title=".NET Regular Expression Tester" href="http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx" target="_blank">http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianshotola.com/index.php/2010/01/19/regular-expression-for-locating-a-password-in-a-connection-string/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
