{"id":234,"date":"2008-02-11T07:03:39","date_gmt":"2008-02-11T07:03:39","guid":{"rendered":"http:\/\/dalelane.co.uk\/blog\/?p=234"},"modified":"2008-02-10T11:04:35","modified_gmt":"2008-02-10T11:04:35","slug":"cryptography-with-c-in-windows-mobile","status":"publish","type":"post","link":"https:\/\/dalelane.co.uk\/blog\/?p=234","title":{"rendered":"Cryptography with C# in Windows Mobile"},"content":{"rendered":"<p>I wrote <a href=\"http:\/\/dalelane.co.uk\/blog\/?p=229\">last week<\/a> about an evening I spent throwing together a password manager for Windows and Windows Mobile. As I wrote at the time, one of the motivations was to try writing some encryption code. <\/p>\n<p>I&#8217;ve finally got around to writing it, and wanted to post it here with a few comments. <\/p>\n<p>This is what I needed code to be able to do:<\/p>\n<ul>\n<li>Encrypt and decrypt data based on a user-provided password\n<\/li>\n<li>Encrypt\/decrypt consistently on both Windows desktops and Windows Mobile devices &#8211; a file encrypted on a Windows Mobile PDA should be able to be decrypted on a Windows desktop, and vice versa\n<\/li>\n<\/ul>\n<p>The System.Security.Cryptography library in .NET makes this fairly straightforward &#8211; the class I have written to add crypto support to the password manager app needed only a few hundred lines of code in total. <\/p>\n<p>I&#8217;ve shared a simplified version of the source at the end of this post.<\/p>\n<p><!--more-->First, a quick walkthrough:<\/p>\n<pre style=\"border: thin solid silver; background-color: #eeeeee; padding: 0.7em; font-size: 1.1em; overflow: auto;\">PasswordDeriveBytes keyGenerator = new PasswordDeriveBytes(password, null);<\/pre>\n<p>We want to be able to generate a unique key from the password that the user enters. We can do this by using <a target=\"_blank\" href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/system.security.cryptography.passwordderivebytes.aspx\">PasswordDeriveBytes<\/a> as a key generator.<\/p>\n<p>This can be used as follows:<\/p>\n<pre style=\"border: thin solid silver; background-color: #eeeeee; padding: 0.7em; font-size: 1.1em; overflow: auto;\">byte[] cryptoKey = keyGenerator.CryptDeriveKey(\"RC2\", \"SHA1\", 128, \r\n                                               new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 });<\/pre>\n<p>Now we have a key, we can use it to initialise a crypto provider:<\/p>\n<pre style=\"border: thin solid silver; background-color: #eeeeee; padding: 0.7em; font-size: 1.1em; overflow: auto;\">RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();\r\nrc2.Key = cryptoKey;<\/pre>\n<p>We also need an IV (initialization vector) to initialise the crypto provider. This needs to be consistent random number. That sounds wrong, doesn&#8217;t it? I just mean that it should be a constant, selected randomly, and ideally kept secret. For this example, I&#8217;m using:<\/p>\n<pre style=\"border: thin solid silver; background-color: #eeeeee; padding: 0.7em; font-size: 1.1em; overflow: auto;\">rc2.IV = new byte[] { 23, 1, 99, 73, 44, 69, 35, 80 };<\/pre>\n<p>To make this library re-usable, I could use something like the application name to generate this value in some way? In this way, different applications that use my crypto DLL will have different IVs.<\/p>\n<p>We can now create the encryptor and decryptors we need to encrypt and decrypt data: <\/p>\n<pre style=\"border: thin solid silver; background-color: #eeeeee; padding: 0.7em; font-size: 1.1em; overflow: auto;\">ICryptoTransform internalEncryptor = rc2.CreateEncryptor();\r\nICryptoTransform internalDecryptor = rc2.CreateDecryptor();<\/pre>\n<p>This can be used to create a <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/system.security.cryptography.cryptostream.aspx\" target=\"_blank\">CryptoStream<\/a>. We can string together a CryptoStream with a StreamReader or StreamWriter to read or write to files.<\/p>\n<p>For example, to create a StreamReader that will read the decrypted contents of a file at the path &#8216;<code>encryptedSourceFilePath<\/code>&#8216;:<\/p>\n<pre style=\"border: thin solid silver; background-color: #eeeeee; padding: 0.7em; font-size: 1.1em; overflow: auto;\">FileStream sourceFileStream = new FileStream(encryptedSourceFilePath, FileMode.Open);\r\nCryptoStream cryptoReader = new CryptoStream(sourceFileStream, internalDecryptor, CryptoStreamMode.Read);\r\nStreamReader encryptedReader = new StreamReader(cryptoReader);<\/pre>\n<p>That now gives you a StreamReader object. <\/p>\n<pre style=\"border: thin solid silver; background-color: #eeeeee; padding: 0.7em; font-size: 1.1em; overflow: auto;\">encryptedReader.ReadLine()<\/pre>\n<p> will read a line from the encrypted file, decrypt it, and return the decrypted string.<\/p>\n<p>We can otherwise use this StreamReader as we would a StreamReader that directly opens a file. <\/p>\n<p>Similarly, we can create a StreamWriter that will encrypt the text given to it and write it to a file at the path &#8216;<code>encryptedDestinationFilePath<\/code>&#8216;:<\/p>\n<pre style=\"border: thin solid silver; background-color: #eeeeee; padding: 0.7em; font-size: 1.1em; overflow: auto;\">FileStream destinationFileStream = new FileStream(encryptedDestinationFilePath, FileMode.Create);\r\nCryptoStream cryptoWriter = new CryptoStream(destinationFileStream, internalEncryptor, CryptoStreamMode.Write);\r\nStreamWriter encryptedWriter = new StreamWriter(cryptoWriter);<\/pre>\n<p>This gives us a StreamWriter object that we can pass strings to.<\/p>\n<pre style=\"border: thin solid silver; background-color: #eeeeee; padding: 0.7em; font-size: 1.1em; overflow: auto;\">encryptedWriter.WriteLine(\"Hello.\");<\/pre>\n<p> will encrypt the &#8220;Hello.&#8221; string and write the encrypted string to the file at the path &#8216;<code>encryptedDestinationFilePath<\/code>&#8216;.<\/p>\n<p>And that&#8217;s it&#8230; it needs some error-handling, and you need to close up streams when you&#8217;ve finished with them, but this is a pretty good start.<\/p>\n<p>Except&#8230; that isn&#8217;t quite it.  \ud83d\ude41<\/p>\n<p>The slightly tricky thing is that I&#8217;ve used <code>PasswordDeriveBytes<\/code> to generate my key. And there isn&#8217;t a <code>PasswordDeriveBytes<\/code> in the .NET Compact Framework that you get on Windows Mobile. <\/p>\n<p>To get around this, I&#8217;ve used the <a href=\"http:\/\/www.opennetcf.com\/library\/sdf\/html\/692b3208-cc00-bd53-93b2-2650ff2a1839.htm\" target=\"_blank\">implementation of PasswordDeriveBytes<\/a> in the <a href=\"http:\/\/www.opennetcf.com\/Products\/SmartDeviceFramework\/tabid\/65\/Default.aspx\">OpenNETCF Smart Device Framework<\/a>. <\/p>\n<p>The <a href=\"http:\/\/opennetcf.com\/Default.aspx?tabid=67\" target=\"_blank\">Community Edition<\/a> of the Smart Device Framework contains a DLL with PasswordDerviceBytes that can be used free-of-charge, and integrates seamlessly with the .NET Compact Framework.<\/p>\n<p>The interface is identical &#8211; the only difference needed in my code is that I use:<br \/>\n<code>OpenNETCF.Security.Cryptography.PasswordDeriveBytes<\/code> instead of<br \/>\n<code>System.Security.Cryptography.PasswordDeriveBytes<\/code>. <\/p>\n<p>More importantly, the behaviour is consistent &#8211; allowing me to use the OpenNETCF SDF implementation on the mobile, and the Microsoft .NET implementation on the desktop.<\/p>\n<p>I&#8217;ve compiled my crypto stream factory class into a DLL, which I can now use in other .NET projects. The first has been my password manager, which is now password-protected and uses encrypted data files. <\/p>\n<p><strong><a href=\"http:\/\/dalelane.co.uk\/blog\/post-images\/CryptoStreamFactory.txt\">Download the source from this post here<\/a><\/strong><\/p>\n<p>As noted above, it is incomplete. Most obviously, it needs error-handling. An approach to determining if you are given the right password more sophisticated than &#8220;go-until-you-throw a Crypto-Exception&#8221; would be good, too. \ud83d\ude42<\/p>\n<p>But this is hopefully enough of a start to be helpful!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I wrote last week about an evening I spent throwing together a password manager for Windows and Windows Mobile. As I wrote at the time, one of the motivations was to try writing some encryption code. I&#8217;ve finally got around to writing it, and wanted to post it here with a few comments. This is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[20,33,36,571,119,117,120,21,118,87,88,22,19],"class_list":["post-234","post","type-post","status-publish","format-standard","hentry","category-code","tag-net","tag-netcf","tag-c","tag-code","tag-crypto","tag-cryptography","tag-csharp","tag-dotnet","tag-opennetcf","tag-password","tag-security","tag-visual-studio","tag-windows-mobile"],"_links":{"self":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/234","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=234"}],"version-history":[{"count":0,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/234\/revisions"}],"wp:attachment":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=234"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=234"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=234"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}