<?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>Tin Isles</title>
	<atom:link href="http://blog.tinisles.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tinisles.com</link>
	<description>My Tech Blathering</description>
	<lastBuildDate>Sat, 24 Nov 2012 06:48:58 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Fixing Mojibake / borked Unicode text</title>
		<link>http://blog.tinisles.com/2012/09/fixing-mojibake-borked-unicode-text/</link>
		<comments>http://blog.tinisles.com/2012/09/fixing-mojibake-borked-unicode-text/#comments</comments>
		<pubDate>Thu, 06 Sep 2012 12:09:09 +0000</pubDate>
		<dc:creator>russ</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.tinisles.com/?p=251</guid>
		<description><![CDATA[Here&#8217;s a problem I&#8217;ve recently hit at work. I hit the google geocode API with a couple of thousand addresses and stored the JSON results. Using the WebClient DownloadString method I didn&#8217;t think to set anything for the encoding. Browsing through the output files I see &#8220;DorfstraÃƒÅ¸e&#8221; where I&#8217;m expecting to see &#8220;Dorfstraße&#8221;. Urgh, mojibake! [...]]]></description>
				<content:encoded><![CDATA[<p>Here&#8217;s a problem I&#8217;ve recently hit at work. I hit the google geocode API with a couple of thousand addresses and stored the JSON results. Using the WebClient <a href="http://msdn.microsoft.com/en-us/library/system.net.webclient.downloadstring.aspx">DownloadString</a> method I didn&#8217;t think to set anything for the encoding. Browsing through the output files I see &#8220;DorfstraÃƒÅ¸e&#8221; where I&#8217;m expecting to see &#8220;Dorfstraße&#8221;. Urgh, <a href="http://en.wikipedia.org/wiki/Mojibake">mojibake</a>!</p>
<p>Here&#8217;s my understanding of what went wrong:</p>
<ul>
<li>Google&#8217;s API serves down the UTF8 bytes for &#8220;Dorfstraße&#8221;: 0&#215;44, 0x6f, 0&#215;72, 0&#215;66, 0&#215;73, 0&#215;74, 0&#215;72, 0&#215;61, <strong>0xc3, 0x9f</strong>, 0&#215;65</li>
<li>WebClient <a href="http://msdn.microsoft.com/en-us/library/system.net.webclient.encoding">Encoding</a> uses the system default.  In my case, Windows-1252.  If I had set this property to UTF8 I wouldn&#8217;t have these Mojibake files.</li>
<li>In UTF8 the ß character is represented with the bytes <a href="http://www.fileformat.info/info/unicode/char/df/index.htm">0xc3, 0x9f</a></li>
<li>WebClient interprets these bytes with Windows-1252 gets: &#8220;DorfstraÃŸe&#8221;</li>
<li>Saving this with <a href="http://msdn.microsoft.com/en-us/library/ms143375.aspx">File.WriteAllText</a> &#8220;uses UTF-8 encoding without a Byte-Order Mark&#8221;. This turns &#8220;DorfstraÃŸe&#8221; into the bytes: 0&#215;44, 0x6f, 0&#215;72, 0&#215;66, 0&#215;73, 0&#215;74, 0&#215;72, 0&#215;61, <strong>0xc3, 0&#215;83, 0xc5, 0xb8</strong>, 0&#215;65</li>
<li>Open the file without a BOM and you see: &#8220;DorfstraÃƒÅ¸e&#8221;</li>
</ul>
<p>I&#8217;ve got the files on my disk.  How would I fix it?  Here&#8217;s the plan to put things in reverse..</p>
<ol>
<li>read in the file bytes and interpret as UTF8 so we are back to &#8220;DorfstraÃŸe&#8221;</li>
<li>get the Western European (Windows) bytes for that string</li>
<li>interpret those bytes as UTF8</li>
</ol>
<p>&#8230;the code:</p>
<p><script src="https://gist.github.com/3655520.js?file=gistfile1.cs"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tinisles.com/2012/09/fixing-mojibake-borked-unicode-text/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Amazon Web Services Presentation</title>
		<link>http://blog.tinisles.com/2012/09/amazon-web-services-presentation/</link>
		<comments>http://blog.tinisles.com/2012/09/amazon-web-services-presentation/#comments</comments>
		<pubDate>Sun, 02 Sep 2012 23:47:54 +0000</pubDate>
		<dc:creator>russ</dc:creator>
				<category><![CDATA[aws]]></category>

		<guid isPermaLink="false">http://blog.tinisles.com/?p=249</guid>
		<description><![CDATA[Well it&#8217;s been a while since I&#8217;ve updated the blog. I have been doing plenty of tinkering just need to write up a &#8216;catch up&#8217; post in the next few days. In the meantime here&#8217;s a presentation I gave on Amazon Web Services for Sydney&#8217;s ALT.NET group. 0:00 Intro 0:43 Quick summary of the services [...]]]></description>
				<content:encoded><![CDATA[<p>Well it&#8217;s been a while since I&#8217;ve updated the blog.  I have been doing plenty of tinkering just need to write up a &#8216;catch up&#8217; post in the next few days.  In the meantime here&#8217;s a presentation I gave on Amazon Web Services for <a href="http://sydney.ozalt.net/">Sydney&#8217;s ALT.NET</a> group.</p>
<p><iframe width="500" height="281" src="http://www.youtube.com/embed/sUSZ4rj-jlw?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<ul>
<li>0:00 Intro</li>
<li>0:43 Quick summary of the services</li>
<li>4:29 Using the services</li>
<li>5:35 Query Request code demo</li>
<li>9:10 EC2 intro</li>
<li>11:36 EC2 code demo</li>
<li>20:29 S3 intro</li>
<li>21:19 S3 / CloudFront code demo</li>
<li>29:21 Mechanic Turk Intro</li>
<li>31:35 Mechanic Turk code demo</li>
</ul>
<p>It&#8217;s best to watch it full screen on the HD resolution.  </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tinisles.com/2012/09/amazon-web-services-presentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Authenticator One-time Password Algorithm in Javascript</title>
		<link>http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/</link>
		<comments>http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 12:46:54 +0000</pubDate>
		<dc:creator>russ</dc:creator>
				<category><![CDATA[cryptography]]></category>

		<guid isPermaLink="false">http://blog.tinisles.com/?p=244</guid>
		<description><![CDATA[I&#8217;ve recently setup 2-factor authentication on my Google account.  The new 2nd factor or &#8220;thing you have&#8221; is a smartphone application which generates 6 digit one-time passwords. I was a bit surprised when I stumbled on this article Two Factor SSH with Google Authenticator. Turns out the algorithm used to generate the OTPs is an [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve recently setup 2-factor authentication on my Google account.  The new 2nd factor or &#8220;thing you have&#8221; is a smartphone application which generates 6 digit one-time passwords.</p>
<p>I was a bit surprised when I stumbled on this article <a href="http://www.mnxsolutions.com/security/two-factor-ssh-with-google-authenticator.html">Two Factor SSH with Google Authenticator</a>. Turns out the algorithm used to generate the OTPs is an open standard. When you set-up an account in the smartphone app you are storing a key that&#8217;s used to create a HMAC of the current time.</p>
<p>You can read the specifics of the algorithm in the <a href="http://tools.ietf.org/id/draft-mraihi-totp-timebased-06.html">TOTP RFC Draft</a>.  I really like the idea that you can use the smartphone app to generate OTPs for your own application.  I&#8217;ve implemented the algorithm in javascript on <a href="http://jsfiddle.net/russau/uRCTk/">jsfiddle</a>.   Javascript is nice and readable, but please don&#8217;t implement your verification client side! <img src='http://blog.tinisles.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><iframe style="width: 100%; height: 1100px" src="http://jsfiddle.net/russau/ch8PK/embedded/result,js,html,resources" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
<p>History</p>
<ul>
<li>20012-Sept-6: <a href="https://github.com/Caligatio/jsSHA">jsSHA</a> moved location</li>
<li>20012-Sept-12: Something suspect about the way I&#8217;m converting BASE32 to bytes.  Changed it to grab full bytes from the binary string, and ignore anything left over.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>A Quick Intro to Facebook&#8217;s Auth + Graph API</title>
		<link>http://blog.tinisles.com/2010/12/a-quick-intro-to-facebooks-auth-graph-api/</link>
		<comments>http://blog.tinisles.com/2010/12/a-quick-intro-to-facebooks-auth-graph-api/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 12:18:14 +0000</pubDate>
		<dc:creator>russ</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.tinisles.com/?p=239</guid>
		<description><![CDATA[Update 2011-02-19: Facebook appear to have changed their documentation a bit; I&#8217;ve just gone through the article to keep everything in line with the Facebook documentation. The old authorization URLs still work, just hoping to save any confusion. Another quick blog article just to settle/document some concepts in my own head, and hopefully provide a [...]]]></description>
				<content:encoded><![CDATA[<p><strong>Update 2011-02-19</strong>: Facebook appear to have changed their documentation a bit; I&#8217;ve just gone through the article to keep everything in line with the Facebook documentation.  The old authorization URLs still work, just hoping to save any confusion.<br />
<hr/>
<p>Another quick blog article just to settle/document some concepts in my own head, and hopefully provide a quick intro to someone out there.</p>
<p>The <a href="http://developers.facebook.com/">Facebook Developers</a> site documents all the APIs that you can use to integrate Facebook.  Coming into this with no knowledge of the API can be pretty overwhelming.  This article is a quick working example of authentication and the graph API.  You can read the Facebook references here:  <a href="http://developers.facebook.com/docs/authentication/">Authentication</a> and <a href="http://developers.facebook.com/docs/api">Graph API</a>.</p>
<p>The authentication here is the OAuth 2.0, this is the protocol you&#8217;d use if you want to write server side code to allow people to log into your site via Facebook, or link existing accounts.  The authentication process also gives you an access token needed to read/write Facebook statuses/photos/etc via the Graph API.</p>
<ul>
<li>First create an application here: <a href="http://developers.facebook.com/setup/">http://developers.facebook.com/setup/</a></li>
<li>You will receive an &lt;App ID&gt; and an &lt;App Secret&gt;</li>
<li>You can use this to build an &#8216;authorize&#8217; URL. This is the location you&#8217;ll send your users to initiate the authentication, e.g. on a &#8216;log in with Facebook&#8217; button on your website:<br />
<del datetime="2011-02-19T03:54:21+00:00">https://graph.facebook.com/oauth/authorize?client_id=<strong>&lt;App ID&gt;</strong>&amp;redirect_uri=http://localhost/blah.aspx&amp;scope=offline_access,publish_stream,user_photos,read_stream</del><br />
https://www.facebook.com/dialog/oauth?client_id=<strong>&lt;App ID&gt;</strong>&#038;redirect_uri=http://localhost/blah.aspx&amp;scope=offline_access,publish_stream,user_photos,read_stream</p>
<ul>
<li>redirect_uri &#8211; the user will be redirected here after they&#8217;ve authorized your application</li>
<li>scope &#8211; the permissions you are requesting to access, more info: <a href="http://developers.facebook.com/docs/authentication/permissions">Extended Permissions</a></li>
<li><del datetime="2011-02-19T03:54:21+00:00">Check out <a href="http://developers.facebook.com/docs/authentication/#dialog-form-factors">Dialog Form Factors</a> to display a pop-up or mobile styled authentication page</del></li>
<li>Check out <a href="http://developers.facebook.com/docs/reference/dialogs/oauth/">OAuth Dialog</a>&#8216;s display property to display a pop-up or mobile styled authentication page</li>
</ul>
</li>
<li>The user is displayed a page to authorize the access your application is requesting:<br />
<a href="http://blog.tinisles.com/wp-content/uploads/2010/12/facebook_authorize.jpg"><img class="aligncenter size-medium wp-image-240" title="facebook_authorize" src="http://blog.tinisles.com/wp-content/uploads/2010/12/facebook_authorize-300x249.jpg" alt="" width="300" height="249" /></a></li>
<li>The user &#8216;allows&#8217; your application and gets redirected back to the location you specified in the authorize URL, with a &lt;code&gt; attached:
<p>http://localhost/blah.aspx?code=<strong>&lt;code&gt;</strong></li>
<li>Your server now takes the code and exchanges it for an access token, performs a GET against the access_token URL:<br />
https://graph.facebook.com/oauth/access_token?client_id=<strong>&lt;App ID&gt;</strong>&amp;redirect_uri=http://localhost/blah.aspx&amp;client_secret=<strong>&lt;App Secret&gt;</strong>&amp;code=<strong>&lt;Code&gt;</strong></li>
<li>Facebook responds with an access token:<br />
access_token=<strong>&lt;access token&gt;</strong></li>
</ul>
<p>Your application is now authorized to read/write data with the permissions of the user via the Graph API.  Hit some URLs to get a JSON response from facebook:</p>
<ul>
<li>The feed: https://graph.facebook.com/me/feed?access_token=<strong>&lt;access token&gt;</strong></li>
<li>Photo albums: https://graph.facebook.com/me/albums?access_token=<strong>&lt;access token&gt;</strong></li>
</ul>
<p>Even better upload a photo on behalf of the user!  Download cURL for your platform: <a href="http://curl.haxx.se/download.html">cURL download</a>.  Run cURL from a command-line:<br />
<code><br />
curl.exe<br />
	-F access_token=&lt;access token&gt;<br />
	-F source=@IMG_2693.jpg<br />
	-F "message=Testing yet again!" https://graph.facebook.com/me/photos<br />
</code></p>
<p>The -F arguments build a form POST, the @ attaches the file as a file upload, don&#8217;t forget to escape any pipe characters in your access_token with a caret.</p>
<p>So that&#8217;s a quick intro to what is possible via the graph and authentication APIs.  I see plenty of other APIs on the developer site I haven&#8217;t tinkered with yet.  If you see anything interesting leave me a comment, and I might pull it apart in a new blog post!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tinisles.com/2010/12/a-quick-intro-to-facebooks-auth-graph-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Amazon Mechanical Turk Quick Intro</title>
		<link>http://blog.tinisles.com/2010/10/amazon-mechanical-turk-quick-intro/</link>
		<comments>http://blog.tinisles.com/2010/10/amazon-mechanical-turk-quick-intro/#comments</comments>
		<pubDate>Tue, 26 Oct 2010 21:53:15 +0000</pubDate>
		<dc:creator>russ</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.tinisles.com/?p=231</guid>
		<description><![CDATA[I&#8217;ve read a bit about Amazon&#8217;s Mechanical Turk, and it sounds like a very interesting technology. It is a market place to put up little tasks for workers around the world to complete, i.e tag a photo, categorize this dress, find an email for the business, etc. Now I&#8217;m wondering what interface you have to [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve read a bit about Amazon&#8217;s <a href="http://mturk.com/">Mechanical Turk</a>, and it sounds like a very interesting technology.  It is a market place to put up little tasks for workers around the world to complete, i.e tag a photo, categorize this dress, find an email for the business, etc.  Now I&#8217;m wondering what interface you have to create tasks, does it work like a facebook app where I host the logic? Finally got around to reading up on it, so here&#8217;s the quick intro for the techie that doesn&#8217;t feel like reading the manual. <img src='http://blog.tinisles.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Creating some tasks is very simple, you just create a HTML template with placeholders like this: ${placeholder}, and some HTML elements.  Upload a CSV to &#8216;mail merge&#8217; with the template, and workers get displayed 1 task for each row in the CSV.  Any data entered into the form fields are saved and available for download.</p>
<p>I came up with an idea for mturk tasks while I was testing an ipad magazine app at work.  The app contains bitmaps exported for the PDF files to create the magazines, so there is no metadata to create hotspots on the index page.  The idea: put the index pages up on mturk for workers to draw the hotspots.  The workers only interact with the HTML in the template, so it is an option to write some javascript to draw the rectangle and store the co-ordinates in hidden form fields.</p>
<p>I want to take 1 index page, and get a rectangle for each page reference.  I&#8217;m not really using mturk to its fullest if I give 1 worker a JPG, and have the worker draw multiple rectangles.  It would be better to &#8220;scale&#8221; the task over multiple workers.  So instead I type all the page numbers into the CSV (this could also be another task!), and each &#8220;task&#8221; displays the worker a single page number, and asks them to draw the rectangle.  Slight problem, what if a page number is listed more than once?  Now I have three columns in my csv:</p>
<ul>
<li>pageNumber &#8211; the page number I want the workers to find</li>
<li>pageCount &#8211; the number of times the page appears</li>
<li>pageUrl &#8211; the location of the scanned page</li>
</ul>
<p>If a page appears multiple times I give the worker multiple rectangles to highlight the page.</p>
<p>So what&#8217;s it look like?  The &#8216;Design&#8217; tab is used to set up the template<br />
<a href="http://blog.tinisles.com/wp-content/uploads/2010/10/mturk_template.jpg"><img src="http://blog.tinisles.com/wp-content/uploads/2010/10/mturk_template-300x106.jpg" alt="" title="Template" width="300" height="106" class="alignnone size-medium wp-image-232" /></a></p>
<p>I upload the CSV, and the task appears for workers to complete.<br />
<a href="http://blog.tinisles.com/wp-content/uploads/2010/10/mturk_worker.jpg"><img src="http://blog.tinisles.com/wp-content/uploads/2010/10/mturk_worker-300x192.jpg" alt="" title="mturk_worker" width="300" height="192" class="alignnone size-medium wp-image-233" /></a></p>
<p>I get a UI of the results in real time, the tasks complete pretty quickly.  I can click the results button and see a grid of the results.  You can also reject the results you see in the grid, and put the task back to the workers for completion.<br />
<a href="http://blog.tinisles.com/wp-content/uploads/2010/10/mturk_batch.jpg"><img src="http://blog.tinisles.com/wp-content/uploads/2010/10/mturk_batch-300x67.jpg" alt="" title="mturk_batch" width="300" height="67" class="alignnone size-medium wp-image-234" /></a></p>
<p>See the rectangles drawn on the index page:<br />
<a href="http://blog.tinisles.com/scraps/mturk/mturk_results_before.html"><img src="http://blog.tinisles.com/wp-content/uploads/2010/10/turk_hotspots.jpg" alt="" title="hotspots" width="195" height="243" class="alignnone size-full wp-image-236" /></a></p>
<p>There is a bit of an overlap on the rectangles, so I wrote a bit of code to &#8216;split the difference&#8217; of any overlap.  See the results <a href="http://blog.tinisles.com/scraps/mturk/mturk_results_after.html">here</a>.</p>
<p>Further reading:</p>
<ol>
<li><a href="http://docs.amazonwebservices.com/AWSMechTurk/latest/RequesterUI/index.html?CreatingaHITTemplate.html">Creating a HIT Template</a> &#8211; a good reference from Amazon on the workings of a HIT created in the UI.</li>
<li><a href="http://docs.amazonwebservices.com/AWSMechTurk/latest/AWSMturkAPI/">API reference</a> &#8211; it is possible to host the IFRAME yourself using an <a href="http://docs.amazonwebservices.com/AWSMechTurk/latest/AWSMturkAPI/index.html?ApiReference_ExternalQuestionArticle.html">ExternalQuestion</a>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.tinisles.com/2010/10/amazon-mechanical-turk-quick-intro/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>LINQ mucking</title>
		<link>http://blog.tinisles.com/2010/10/linq-mucking/</link>
		<comments>http://blog.tinisles.com/2010/10/linq-mucking/#comments</comments>
		<pubDate>Tue, 12 Oct 2010 11:37:55 +0000</pubDate>
		<dc:creator>russ</dc:creator>
				<category><![CDATA[linq]]></category>
		<category><![CDATA[timezones]]></category>

		<guid isPermaLink="false">http://blog.tinisles.com/?p=230</guid>
		<description><![CDATA[Another quick one! Forcing myself to learn LINQ, so I decided to rewrite some looping code. The original code; simple enough, loop thru all the daylight adjustments for a timezone and build a list of date/time and offset. List&#60;TransitionOffset&#62; transitions = new List&#60;TransitionOffset&#62;(); foreach (TimeZoneInfo.AdjustmentRule adj in TimeZoneInfo.FindSystemTimeZoneById(&#34;AUS Eastern Standard Time&#34;).GetAdjustmentRules()) { if (adj.DateEnd.Year &#62;= [...]]]></description>
				<content:encoded><![CDATA[<p>Another quick one!  Forcing myself to learn LINQ, so I decided to rewrite some looping code.  The original code; simple enough, loop thru all the daylight adjustments for a timezone and build a list of date/time and offset.</p>
<pre class="brush: c#">
List&lt;TransitionOffset&gt; transitions = new List&lt;TransitionOffset&gt;();
foreach (TimeZoneInfo.AdjustmentRule adj in TimeZoneInfo.FindSystemTimeZoneById(&quot;AUS Eastern Standard Time&quot;).GetAdjustmentRules())
{
    if (adj.DateEnd.Year &gt;= 2010)
    {
        for (int year = 2010; year &lt;= 2015; year++)
        {
            transitions.Add(new TransitionOffset
            {
                Transition = GetDateTime(year, adj.DaylightTransitionStart),
                Offset = adj.DaylightDelta.TotalHours
            });
            transitions.Add(new TransitionOffset
            {
                Transition = GetDateTime(year, adj.DaylightTransitionEnd),
                Offset = 0
            });

        }
    }
}
transitions = transitions.OrderBy(t =&gt; t.Transition).ToList();
</pre>
<p>..and again in LINQ</p>
<pre class="brush: c#">
var zoneAdjs = from adj in TimeZoneInfo.FindSystemTimeZoneById(&quot;AUS Eastern Standard Time&quot;).GetAdjustmentRules()
                where adj.DateEnd.Year &gt;= 2010
                from year in Enumerable.Range(2010, 6)
                let trans = new[] { 
                                        new { Transition = GetDateTime(year, adj.DaylightTransitionEnd), 
                                            Offset = 0.0},
                                        new { Transition = GetDateTime(year, adj.DaylightTransitionStart),
                                        Offset = adj.DaylightDelta.TotalHours}
                                    }
                from tran in trans
                orderby tran.Transition
                select tran;
</pre>
<p>Any more readable / maintainable than the non-LINQ version?  It definitely took longer to write while I&#8217;m a LINQ &#8220;newbie&#8221;.  The most complicated bit was pulling the DaylightTransitionEnd and DaylightTransitionStart into one collection.  This collection is only ever used to create JSON, so I like being able to serialize anonymous types from LINQ, and skip creating classes that are only used to serialize.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tinisles.com/2010/10/linq-mucking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TwitterHeatmap.com</title>
		<link>http://blog.tinisles.com/2010/09/twitterheatmap-com/</link>
		<comments>http://blog.tinisles.com/2010/09/twitterheatmap-com/#comments</comments>
		<pubDate>Mon, 13 Sep 2010 11:54:21 +0000</pubDate>
		<dc:creator>russ</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.tinisles.com/?p=227</guid>
		<description><![CDATA[I had some time on the weekend to do some coding, so I &#8220;finished&#8221; a project I&#8217;ve spent a few nights playing with. The idea was to pull together some visualization of the twitter sample feed.   A work colleague (spud) suggested a heatmap where the points fade out over a few frames.  And here [...]]]></description>
				<content:encoded><![CDATA[<p>I had some time on the weekend to do some coding, so I &#8220;finished&#8221; a project I&#8217;ve spent a few nights playing with.</p>
<p>The idea was to pull together some visualization of the twitter <a href="http://dev.twitter.com/pages/streaming_api_methods#statuses-sample">sample</a> feed.   A work colleague (spud) suggested a heatmap where the points fade out over a few frames.  And here it is: <a href="http://twitterheatmap.com/">http://twitterheatmap.com/</a></p>
<p>I&#8217;ve got an EXE running on an EC2 micro instance dropping XML files of all the tweets into a folder.  Another EXE fires once a day at midnight UTC, generates the JPGs, creates an AVI (with <a href="http://www.virtualdub.org/">VirtualDub</a>), and uploads the video to youtube.   The data you see live right now is a bit flakey &#8211; displaying a fail whale where I don&#8217;t have any data. <img src='http://blog.tinisles.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Grabbed a lot of handy code off the net to build this:</p>
<ul>
<li><a href="http://www.jgiesen.de/map/index.html">Day and Night Map</a> &#8211; code to draw the day / night terminator</li>
<li><a href="http://dylanvester.com/post/Creating-Heat-Maps-with-NET-20-%28C-Sharp%29.aspx">Creating Heat Maps with .NET 2.0 (C#)</a></li>
<li><a href="http://www.geckonewmedia.com/blog/2009/8/14/jquery-youtube-playlist-plugin---youtubeplaylist">jQuery youtube playlist plugin &#8211; youtubeplaylist | Gecko New Media Blog</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.tinisles.com/2010/09/twitterheatmap-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>App Engine&#8217;s High-Performance Image Serving</title>
		<link>http://blog.tinisles.com/2010/08/app-engines-high-performance-image-serving/</link>
		<comments>http://blog.tinisles.com/2010/08/app-engines-high-performance-image-serving/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 03:00:15 +0000</pubDate>
		<dc:creator>russ</dc:creator>
				<category><![CDATA[appengine]]></category>

		<guid isPermaLink="false">http://blog.tinisles.com/?p=225</guid>
		<description><![CDATA[Real quick blog post while I eat my lunch&#8230;. Google released a SDK 1.3.6 for App Engine yesterday: Google App Engine Blog: Multi-tenancy Support, High Performance Image Serving, Increased Datastore Quotas and More Delivered In New App Engine Release. Of particular interest to me was the High Performance Image Serving. High-Performance Image Serving This release [...]]]></description>
				<content:encoded><![CDATA[<p>Real quick blog post while I eat my lunch&#8230;.</p>
<p>Google released a SDK 1.3.6 for App Engine yesterday: <a href="http://googleappengine.blogspot.com/2010/08/multi-tenancy-support-high-performance_17.html">Google App Engine Blog: Multi-tenancy Support, High Performance Image Serving, Increased Datastore Quotas and More Delivered In New App Engine Release</a>.  Of particular interest to me was the High Performance Image Serving.</p>
<blockquote><p>High-Performance Image Serving This release also includes a new, high-performance image serving system for your applications, based on the same infrastructure we use to serve images for Picasa. This feature allows you to generate a stable, dedicated URL for serving web-suitable image thumbnails &#8230; This special URL can serve that image resized and/or cropped automatically, and serving from this URL does not incur any CPU or dynamic serving load on your application (though bandwidth is still charged as usual).
</p></blockquote>
<p>So I store some images in an App Engine blob, pass this to <a href="http://code.google.com/appengine/docs/python/images/functions.html#Image_get_serving_url">get_serving_url</a> and Google give me back a URL for the &#8216;high performance&#8217; location.  I was just interested to see what the URL would look like, and where it would actually be hosted.  So I whipped up something real quick to grab the URL ..and here&#8217;s what it looks like:</p>
<p><code>http://lh5.ggpht.com/FIl4UGix2IbadeLOotXq2CgIF4Wi4xUSaSegSDSrfnIy5YyQlZWWaPcDRhyxkJTGepVkxNHUVcv8o1_1zWazbg=s200</code></p>
<p>Note this URL has the &#8220;=s200&#8243; parameter to scale the image down to 200px wide.  You can also pass along a crop parameter to crop the image down to a small square, e.g: <a href="http://lh5.ggpht.com/FIl4UGix2IbadeLOotXq2CgIF4Wi4xUSaSegSDSrfnIy5YyQlZWWaPcDRhyxkJTGepVkxNHUVcv8o1_1zWazbg=s200-c">=s200-c</a></p>
<p>The code is a hacked up version of the <a href="http://code.google.com/appengine/docs/python/images/usingimages.html">image upload</a> and <a href="http://code.google.com/appengine/docs/python/blobstore/overview.html">blob storage</a> examples.</p>
<pre class="brush: python">
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.api import images
from google.appengine.api import urlfetch
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db

class ImageModel(db.Model):
    image = db.BlobProperty()
		


class MainPage(webapp.RequestHandler):
	def get(self):
		upload_url = blobstore.create_upload_url(&#39;/upload&#39;)

		self.response.out.write(&quot;&quot;&quot;&lt;html&gt;&lt;head&gt;&lt;title&gt;High Performance Image Tester&lt;/title&gt;&lt;/head&gt;&quot;&quot;&quot;);
		self.response.out.write(&quot;&quot;&quot;&lt;body&gt;&quot;&quot;&quot;);
		self.response.out.write(&quot;&quot;&quot;
				&lt;form action=&quot;%s&quot; enctype=&quot;multipart/form-data&quot; method=&quot;post&quot;&gt;
				&lt;div&gt;&lt;label&gt;Image:&lt;/label&gt;&lt;/div&gt;
				&lt;div&gt;&lt;input type=&quot;file&quot; name=&quot;file&quot;/&gt;&lt;/div&gt;
				&lt;div&gt;&lt;input type=&quot;submit&quot; value=&quot;Upload&quot;&gt;&lt;/div&gt;
				&lt;/form&gt;
			&lt;/body&gt;
			&lt;/html&gt;&quot;&quot;&quot; % upload_url)


class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        upload_files = self.get_uploads(&#39;file&#39;)  # &#39;file&#39; is file upload field in the form
        blob_info = upload_files[0]
        self.redirect(&#39;/serve/%s&#39; % blob_info.key())

class ServeHandler(webapp.RequestHandler):
	def get(self,resource):
		self.response.out.write(&quot;%s %s %s&quot; % (images.get_serving_url(resource, 32),
		images.get_serving_url(resource, 150),
		images.get_serving_url(resource, 80)))

application = webapp.WSGIApplication(
	[(&#39;/&#39;, MainPage),
	(&#39;/upload&#39;, UploadHandler),
	(&#39;/serve/([^/]+)?&#39;, ServeHandler)],

	debug=True)

def main():
	run_wsgi_app(application)

if __name__ == &quot;__main__&quot;:
	main()
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.tinisles.com/2010/08/app-engines-high-performance-image-serving/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Subject Alternative Names for SSL</title>
		<link>http://blog.tinisles.com/2010/08/subject-alternative-names-for-ssl/</link>
		<comments>http://blog.tinisles.com/2010/08/subject-alternative-names-for-ssl/#comments</comments>
		<pubDate>Mon, 02 Aug 2010 12:09:43 +0000</pubDate>
		<dc:creator>russ</dc:creator>
				<category><![CDATA[cryptography]]></category>
		<category><![CDATA[networking]]></category>

		<guid isPermaLink="false">http://blog.tinisles.com/?p=218</guid>
		<description><![CDATA[Last time I blogged about SSL and host-headers I was convinced it is only possible to host multiple SSL sites on one IP address when using a wildcard certifcate. I think I was right at the time, and now comes along Unified Communications UC SSL Certificates (aka Subject Alternative Name). Same issue as before: host-headers [...]]]></description>
				<content:encoded><![CDATA[<p>Last time I <a href="http://blog.tinisles.com/2008/11/iis-ssl-and-host-headers/">blogged about SSL and host-headers</a> I was convinced it is only possible to host multiple SSL sites on one IP address when using a wildcard certifcate.  I <em>think</em> I was right at the time, and now comes along <a href="http://www.sslshopper.com/unified-communications-uc-ssl-certificates.html">Unified Communications UC SSL Certificates</a> (aka <a href="http://en.wikipedia.org/wiki/Subject_Alternative_Name">Subject Alternative Name</a>).</p>
<p>Same issue as before: host-headers enable you to host several websites on a single IP address.  We run into a problem with several SSL certificates on one IP address.  The first message a server sends in the SSL handshake contains relevant certificate, the server can only determine which certificate by IP address / port.  If there is only one certificate to serve &#8211; no need to make a decision!  Here we can serve a UC SSL certificate which is accepted by the web browser for <em>multiple</em> domain names.</p>
<p>I felt like trying this myself, extra curious to know what the certificate will look like in a browser.  Managed to get this working in OpenSSL using a combination of two articles:</p>
<ol>
<li><a href="http://www.dylanbeattie.net/docs/openssl_iis_ssl_howto.html">Creating a Self-Signed Certificate using OpenSSL for use with Microsoft Internet Information Services (IIS) 5</a></li>
<li><a href="http://therowes.net/~greg/2008/01/08/creating-a-certificate-with-multiple-hostnames/">Creating a Certificate With Multiple Hostnames</a></li>
</ol>
<p>Follow the steps for creating a CA in the first article.  Grab the CA and import it into your IIS box.  Switch over to the second article and add the changes to the openssl.cfg</p>
<pre class="brush: text">[ CA_default ]
copy_extensions = copy

[ req ]
req_extensions = v3_req

[ v3_req ]

# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# Some CAs do not yet support subjectAltName in CSRs.
# Instead the additional names are form entries on web
# pages where one requests the certificate...
subjectAltName          = @alt_names

[alt_names]
DNS.1   = stoniessl.info
DNS.2   = freemegahost.info
</pre>
<p>Create a key for the multi domain certificate.  Here we are skipping the &#8220;create CSR on IIS&#8221; step, and creating the key in OpenSSL.</p>
<pre>openssl genrsa -des3 -out keys\multi.key 1024</pre>
<p>Create a certificate request</p>
<pre>openssl req -new -out requests\multi.txt -key keys\multi.key</pre>
<p>Sign the certificate request</p>
<pre>openssl.exe ca -policy policy_anything -cert certs\ca.cer -in requests\multi.txt -keyfile keys\ca.key -out multi.cer</pre>
<p>Export the certificate AND private key (usually the private key would already be on in IIS box if you created the CSR in IIS)</p>
<pre>openssl.exe pkcs12 -export -out multi.pfx -in multi.cer -inkey keys\multi.key</pre>
<p>You now have a UC SSL cert you can install on the IIS box.  By default IIS won&#8217;t allow you to enter a host-header when you are setting the SSL binding.  There&#8217;s a little trick from this article: <a href="http://blog.armgasys.com/?p=80">Using Host Headers and SLL in IIS 7</a> &#8211; give the certificate a friendly name starting with &#8216;*&#8217;!</p>
<p>And what does the certificate look like?  Here it is, in IE and FF:</p>
<p><a href="http://blog.tinisles.com/wp-content/uploads/2010/08/multi_certificate.jpg"><img class="alignnone size-medium wp-image-220" title="UC certificates" src="http://blog.tinisles.com/wp-content/uploads/2010/08/multi_certificate-300x195.jpg" alt="" width="300" height="195" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tinisles.com/2010/08/subject-alternative-names-for-ssl/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Should you trust lastpass.com?</title>
		<link>http://blog.tinisles.com/2010/01/should-you-trust-lastpass-com/</link>
		<comments>http://blog.tinisles.com/2010/01/should-you-trust-lastpass-com/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 12:39:00 +0000</pubDate>
		<dc:creator>russ</dc:creator>
				<category><![CDATA[cryptography]]></category>

		<guid isPermaLink="false">http://blog.tinisles.com/2010/01/should-you-trust-lastpass-com/</guid>
		<description><![CDATA[lastpass.com looks like a handy online service for storing all your website passwords. Browser extensions are available to make the whole process easier. If you use the web from several PCs it does sound nice to have all your passwords available and synced between your PCs. First thought was wether I should hand over my [...]]]></description>
				<content:encoded><![CDATA[<p><a href="https://lastpass.com/">lastpass.com</a> looks like a handy online service for storing all your website passwords.  Browser extensions are available to make the whole process easier.  If you use the web from several PCs it does sound nice to have all your passwords available and synced between your PCs.</p>
<p>First thought was wether I should hand over my passwords to the 3rd party, hopefully they are storing them with some serious crypto.  Perusing their <a href="https://lastpass.com/support_faqs.php">FAQ</a> I found some info on this:</p>
<blockquote><p>We only support keeping the encryption done on your computer so LastPass can&#8217;t see your sensitive data</p></blockquote>
<blockquote><p>&#8230;your sensitive data is always encrypted and decrypted locally on your computer before being synchronized. Your master password never leaves your computer and your key never leaves your computer. No one at LastPass (or anywhere else) can decrypt your data without you giving up your password (we will never ask you for it). Your key is created by taking a SHA-256 hash of your password. When you login, we make a hash of your username concatenated with your password, and that hash is what&#8217;s sent to verify if you can download your encrypted data.</p></blockquote>
<p>So they are encrypting everything with a key derived from your password &#8211; plus they don&#8217;t know your password &#8211; so they CANNOT access any of your passwords.  Nice.  But why stop there?  Let&#8217;s fire up fiddler to make sure they definitely don&#8217;t have my passwords.</p>
<p>I&#8217;ve created a junk account on lastpass username: russell.sayers.junk@gmail.com, password: test1234 (the account will be gone by the time you read this!).  The first form I see submitted to the server is when I create my account:</p>
<table>
<tr>
<td>username </td>
<td>russell.sayers.junk@gmail.com</td>
</tr>
<tr>
<td>hash </td>
<td>53c81a859a3f3d4dc3762d3a47bab07fad7ad3f2673724deb20fb420e8bdc03a</td>
</tr>
<tr>
<td>password </td>
<td>********</td>
</tr>
<tr>
<td>password2 </td>
<td>********</td>
</tr>
<tr>
<td>password_hint</td>
<td>testing</td>
</tr>
<tr>
<td>timezone2 </td>
<td>+10:00,1</td>
</tr>
<tr>
<td>language2 </td>
<td>en-US</td>
</tr>
<tr>
<td>agree </td>
<td>on</td>
</tr>
<tr>
<td>agreeupload </td>
<td>on</td>
</tr>
<tr>
<td>loglogins </td>
<td>on</td>
</tr>
<tr>
<td>improve </td>
<td>on</td>
</tr>
<tr>
<td>json </td>
<td>1</td>
</tr>
</table>
<p>I don&#8217;t see my password going to their servers in the clear.  I can confirm that the hash getting sent is geniune by creating the same hash elsewhere via an online <a href="http://www.xorbin.com/tools/sha256-hash-calculator">SHA256 generator</a>, or writing some code myself.  Try it yourself, the hash created is SHA256(SHA256(username + password) + password) &#8211; everything checks out.  All the C# code to verify the encryption/hashing is at the end of the article.</p>
<p>The login form:</p>
<table>
<tr>
<td>method</td>
<td>web</td>
</tr>
<tr>
<td>hash</td>
<td>53c81a859a3f3d4dc3762d3a47bab07fad7ad3f2673724deb20fb420e8bdc03a</td>
</tr>
<tr>
<td>username</td>
<td>russell.sayers.junk@gmail.com</td>
</tr>
<tr>
<td>encrypted_username</td>
<td>T2tBleI3PxuLOoNEwNkv5PZ/rYr5dDIoYZS+We4vER4=</td>
</tr>
<tr>
<td>otp</td>
<td></td>
</tr>
<tr>
<td>gridresponse</td>
<td></td>
</tr>
<tr>
<td>trustlabel</td>
<td></td>
</tr>
<tr>
<td>uuid</td>
<td></td>
</tr>
<tr>
<td>sesameotp</td>
<td></td>
</tr>
<tr>
<td>email</td>
<td>russell.sayers.junk@gmail.com</td>
</tr>
<tr>
<td>password</td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
<p>Again the same hash is being used to verify me when I login.  I can see an encrypted username is being sent (although I&#8217;m not sure why?), rooting around in the javascript I can see the key being used for encyption is SHA(username+password).  Importantly this is different to the hash being used to authenticate me &#8211; as we don&#8217;t want the server to be able to decypt anything encypted by the client, i.e. they would have to know my password to derive the same key on their side.</p>
<p>The form to add a new website:<br />
<a href="http://blog.tinisles.com/blogger-images/2010/01/lg_lastpass_add.JPG"><img src="http://blog.tinisles.com/blogger-images/2010/01/sm_lastpass_add.JPG" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 307px;" /></a></p>
<table>
<tr>
<td>hasplugin</td>
<td>0</td>
</tr>
<tr>
<td>extjs</td>
<td>1</td>
</tr>
<tr>
<td>search</td>
<td></td>
</tr>
<tr>
<td>purgeext</td>
<td>0</td>
</tr>
<tr>
<td>deleteext</td>
<td></td>
</tr>
<tr>
<td>undeleteext</td>
<td>0</td>
</tr>
<tr>
<td>ajax</td>
<td>1</td>
</tr>
<tr>
<td>ob</td>
<td></td>
</tr>
<tr>
<td>basic_auth</td>
<td>0</td>
</tr>
<tr>
<td>isbookmark</td>
<td>0</td>
</tr>
<tr>
<td>openid_url</td>
<td></td>
</tr>
<tr>
<td>aid</td>
<td>0</td>
</tr>
<tr>
<td>useurid</td>
<td>0</td>
</tr>
<tr>
<td>fromwebsite</td>
<td>1</td>
</tr>
<tr>
<td>name</td>
<td>pyJlY+AX0Aoczlx50hwlHg==</td>
</tr>
<tr>
<td>grouping</td>
<td></td>
</tr>
<tr>
<td>origurl</td>
<td></td>
</tr>
<tr>
<td>url</td>
<td>66616365626f6f6b2e636f6d</td>
</tr>
<tr>
<td>username</td>
<td>ICkGIGAn7SIk16iKNkl3DA==</td>
</tr>
<tr>
<td>password</td>
<td>dl78FYUSIdsxxSdkBuBWEA==</td>
</tr>
<tr>
<td>extra</td>
<td>faESoIpzmCQg5PeHpXN0GQ==</td>
</tr>
</table>
<p>We can see here the client is sending encyrypted versions of name, username, password, and the extra info.  Again this is encrypted with a key we only have on our client &#8211; no one at lastpass could have this key.  For some reason the URL is being sent in a HEX representation of the string &#8211; not sure why they aren&#8217;t just sending the string?
</p>
<p>So when I log back into lastpass, I can drill down into this entry and see it again.  Let&#8217;s make sure everything looks okay here.  The HTML that renders this screen is available in fiddler:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="brush: html">
&lt;tr&gt;
  &lt;td class='col1'&gt;Name&lt;/td&gt;
  &lt;td&gt;&lt;input name='name' id='name' type='text' value='pyJlY+AX0Aoczlx50hwlHg==' style='width: 250px'&gt;&lt;/td&gt;
&lt;/tr&gt;
...
&lt;tr&gt;
  &lt;td class='col1'&gt;Username&lt;/td&gt;
  &lt;td&gt;&lt;input name='username' id='idusername' type='text' value='SgVkuVKH4MjkP+Saz64UhA=='&gt;&#160;&lt;/td&gt;
&lt;/tr&gt;
...
&lt;tr&gt;
  &lt;td class='col1'&gt;Notes&lt;/td&gt;
  &lt;td&gt;&lt;textarea name='extra' id='extra' rows='6' cols='35'&gt;1rZ3sSuggtdavyCu446GZA==&lt;/textarea&gt;&lt;/td&gt;
&lt;/tr&gt; </pre>
<p>The server is sending down our encrypted details, and relying on the client to decrypt everything.
</p>
<p>So, yes &#8211; you CAN trust lastpass.com with your passwords!  Don&#8217;t just take my word for it; fire up Fiddler, and compare the hashed/encrypted values with what you expect.</p>
<p>Lastly the c# code to confirm the AES encrypted strings above are geniune.</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="brush: csharp">
static void Main(string[] args)
{
    string username = &quot;russell.sayers.junk@gmail.com&quot;;
    string password = &quot;test1234&quot;;
    string hash_auth = ByteArrayToHexString(SHA256(ByteArrayToHexString(SHA256(username+password)) + password));
    byte[] hash_key = SHA256(username + password);

    Console.WriteLine(&quot;hash for authentication =&gt; &quot; + hash_auth);
    Console.WriteLine(&quot;hash for encryption =&gt; &quot; +  ByteArrayToHexString(hash_key));
    Console.WriteLine(&quot;'{0}' encrypted =&gt; {1}&quot;, username, Encrypt(username, hash_key, &quot;&quot;));
    Console.WriteLine(&quot;'{0}' encrypted =&gt; {1}&quot;, &quot;facebook&quot;, Encrypt(&quot;facebook&quot;, hash_key, &quot;&quot;));
    Console.WriteLine(&quot;'{0}' encrypted =&gt; {1}&quot;, &quot;cryptolearner&quot;, Encrypt(&quot;cryptolearner&quot;, hash_key, &quot;&quot;));
    Console.WriteLine(&quot;'{0}' encrypted =&gt; {1}&quot;, &quot;password&quot;, Encrypt(&quot;password&quot;, hash_key, &quot;&quot;));
    Console.WriteLine(&quot;'{0}' encrypted =&gt; {1}&quot;, &quot;no notes&quot;, Encrypt(&quot;no notes&quot;, hash_key, &quot;&quot;));
}

static byte[] SHA256(string data)
{
    byte[] indata = Encoding.UTF8.GetBytes(data);
    SHA256 shaM = new SHA256Managed();
    return shaM.ComputeHash(indata);
}

/// &lt;remarks&gt;From http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3928b8cb-3703-4672-8ccd-33718148d1e3&lt;/remarks&gt;
static string ByteArrayToHexString(byte[] data)
{
    StringBuilder sb = new StringBuilder(data.Length * 2);
    foreach (byte b in data)
    {
        sb.AppendFormat(&quot;{0:x2}&quot;, b);
    }
    return sb.ToString();
}

/// &lt;remarks&gt;From http://stackoverflow.com/questions/1079131/c-aes-256-encryption&lt;/remarks&gt;
static public string Encrypt(string plaintext, byte[] KeyBytes, string InitialVector)
{
    byte[] PlainTextBytes = Encoding.UTF8.GetBytes(plaintext);
    byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
    RijndaelManaged SymmetricKey = new RijndaelManaged();
    SymmetricKey.Mode = CipherMode.ECB;
    SymmetricKey.Padding = PaddingMode.PKCS7;
    ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes);
    MemoryStream MemStream = new MemoryStream();
    CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write);
    CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
    CryptoStream.FlushFinalBlock();
    byte[] CipherTextBytes = MemStream.ToArray();
    MemStream.Close();
    CryptoStream.Close();
    return Convert.ToBase64String(CipherTextBytes);
}</pre>
</p>
<p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tinisles.com/2010/01/should-you-trust-lastpass-com/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
