About the author

J Sawyer is a developer based in Houston, TX and loves to write code, especially ASP.NET and other web-related stuff.

He also loves to ride his Kawasaki Ninja.

But he doesn't code and ride at the same time.

Calendar

<<  March 2010  >>
MoTuWeThFrSaSu
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar

Notes on Symmetric Cryptography

December 30, 2007 11:19 PM

Howdy y'all.  Me again.  I've gotten a lot of questions about doing crypto in .Net ... for some reason, it's been something that interests me quite a bit.  Now, there are a bunch of resources out there on this, but it's (apparently) not always easy to find.  So, I'm going to put some tips and thoughts here. 

First, let me say this: .Net has awesome support for crypto. This support is in the System.Security.Cryptography namespace (or a sub-namespace under that) with most of the classes implemented in mscorlib.   I'm going to focus on symmetric encryption here (I'll deal with the others later) Symmetric encryption is reversable (you can get the clear text from the crypto text) and is based on a single key. There are several symmetric algorithms included with .Net, and all of their implementation classes derive from System.Security.Cryptography.SymmetricAlgorithm abstract class:

  • DES (Data Encryption Standard) (FX 1.0+) : This was the Federal Information Processing Standard (FIPS) starting in 1976. It has a 56-bit key, so with today's modern computers, it is subject to a brute-force attack in a trivial amount of time. It's not recommended for general usage anymore, but it has been so widely used for so long that it's not wise to not include it.
  • TripleDES (FX 1.0+): Also commonly referred to a 3DES.  Basically, as it's name implies, it's DES 3 times over.  There are (usually) 3 DES keys and the cipher is run through the three keys on successive passes.  There are actually several variations on the theme that are out and about, some using 2 keys, some using 1 key but, in general, the most common method is three keys. 
  • Rijndael (FX 1.0+): This was the algorithm that as become the Advanced Encryption Standard (AES) and is the replacement for 3DES.  It supports 128, 192 and 256 bit keys. To put this in perspective, if a machine could recover a DES key in a second (using brute force), it would take approximately 149 trillion years to crack a 128-bit AES key (see http://csrc.nist.gov/archive/aes/index.html)  It was the finalist in an exhaustive analysis process by the National Institues of Standards and Technology (NIST) with input from the US National Security Agency (or No Such Agency, depending on your viewpoint) to determine the next FIPS algorithm.  It was selected for its high level of security as well as it's efficiency on modern processors (DES and 3DES were notoriously inefficient).  The other algorithms were considered secure enough for non-classified information, but only Rijndael was considered secure enough for classified information.  For details on the algorithm, see http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf.  Now, if you understand that stuff, let me know.  Perhaps you could explain it to me in English.
  • AES (Fx 3.5): This is a FIPS-certified implementation of Rijndael.  And yes, this is a big deal, especially for organizations that deal with the US government and, particularly, the DoD. For classified information, the key must be 192 or 256 bits.

Now, because the all derive from the same base class, using them is pretty much the same (with the exception of key sizes).  Here's a code sample (with comments):

public static byte[] EncryptText(string clearText)
{
    //Create our algorithm. 
    using (SymmetricAlgorithm alg = Rijndael.Create())
    {
        //Can also use: 
        //SymmetricAlgorithm alg = SymmetricAlgorithm.Create("Rijndael");
        //For clarity, we'll generate the key.  
        //In the real world, you'll likely get this from ... somewhere ... 
        alg.GenerateKey();
        //An initialization vector is important for true security of the algorithm. 
        alg.GenerateIV();
        //Create our output stream for the cipherText
        //We're using a memory stream here, but you can use 
        //any writable stream (i.e. FileStream)
        System.IO.Stream outputStream = new System.IO.MemoryStream();
        //Create the crypto stream that the algorithm will use.  
        CryptoStream crypStream = new CryptoStream(outputStream,
            alg.CreateEncryptor(), CryptoStreamMode.Write);
        //Now we need to read from the stream
        //This will be a stream reader that reads from the crypto stream. 
        //This writer will write to the CryptoStream
        using (System.IO.StreamWriter inputWriter = new System.IO.StreamWriter(crypStream))
        {
            //Write to the stream writer ... this writes to the underlying CryptoStream
            inputWriter.Write(clearText);
            //Not usually necessary, but just to be sure. 
            inputWriter.Flush();
        }
        //The encrypted data is now ready to read. 
        //If we were using, say, a FileStream for the output, we wouldn't need to do this. 
        //Create a binary reader to read it into a byte array.  
        using (System.IO.BinaryReader outputReader = new System.IO.BinaryReader(outputStream))
        {
            //Read the bytes.
            byte[] cipherBytes = new byte[outputStream.Length];
            int dataRead = outputReader.Read(cipherBytes, 0, cipherBytes.Length);
        }
        //Make sure we close the other streams. 
        outputStream.Close();
        crypStream.Close(); 
        //... and return ... 
        return cipherBytes;
    }
}

So ... the comments do tell a lot of the story, but not all.  What is an IV?  No, it's not a needle ... it's an initialization vector.  This is an extra bit of random gobbledygook that is added into the beginning of the clear text before it is run through the cipher.  This is actually very important to do.  You see, these algorithms are block ciphers, meaning that they encrypt blocks at a time.  By default, they are done in CipherBlockChaining (CBC) mode, where some of the previous block of cipher text is fed into the next block.  This helps increase the randomness of the cipher text.  However, if the clear text starts with the same pattern (not very uncommon), then the beginning of the cipher text will also be the same.  Not good as it helps a bad guy reduce the key space.  So ... the IV prevents that from happening. You can store the IV separately from the cipher text (in the clear ... bad guys can't get anything useful from it) or you can prepend the returned cipher text with it (so the return is [IV][cipher text]).  I prefer the second ... it's a touch of security by obscurity (this isn't bad as long as it's not the only thing that you rely on ... it can be a part of a complete defense-in-depth strategy).

Decrypting is very similar ... the same process (and almost the same code) in reverse.  Here's a sample with less comments (many of the comments above also apply here).

public static string DecryptText(byte[] cipherText)
{
    using (SymmetricAlgorithm alg = Rijndael.Create())
    {
        //These will come from somewhere. 
        alg.Key = ourKey;
        alg.IV = ourIV; 

        System.IO.Stream outputStream = new System.IO.MemoryStream();

        //Create the crypto stream. 
        //This is the biggest difference between encryption and decryption. 
        CryptoStream crypStream = new CryptoStream(outputStream,
            alg.CreateEncryptor(), CryptoStreamMode.Read);

        //Also a slightly different write because we have bytes to write. 
        using (System.IO.BinaryWriter inputWriter = new System.IO.BinaryWriter(crypStream))
        {
            inputWriter.Write(cipherText); 
            inputWriter.Flush();
        }
        //The decrypted data is now ready to read. 
        //If we were using, say, a FileStream for the output, we wouldn't need to do this. 
        //Create a binary reader to read it into a byte array.  
        string clearText; 
        using (System.IO.StringReader outputReader = new System.IO.StringReader(outputStream))
        {
            clearText = outputReader.ReadToEnd(); 
        }
        //Make sure we close the other streams. 
        outputStream.Close();
        crypStream.Close();
        //... and return ... 
        return clearText;
    }
}

Some final comments:

  • I like to have all of the disposable objects in their own using blocks.  I didn't do that here to minimize the nesting of the using blocks for the sake of clarity.  That said, I'm a big fan of using blocks.  That's my story and I'm sticking to it.
  • I didn't talk about key storage.  That's the stickiest part of using symmetric algorithms.  I'll deal with that in a later post. Here's a clue: DPAPI.
  • If you notice, the encrypt and the decrypt functions are almost identical.  Yes, it is possible to have both operations in one function, with a bool indicating encryption/decryption. I, personally, like to do this.  I did not do that here for the sake of clarity and a clear separation between the two processes.  I'm sure you can look at the samples above and make that happen.
  • You can store the byte arrays as text/string.  To do that, use this snippet: string cipherString = System.Convert.ToBase64String(data);
  • This really is pretty easy.  It's very straightforward.  If you think it's hard, try reading the documentation for the Win32 CryptoAPI.  It's called the CryptoAPI that because it's cryptic.  It will make your brain hurt.  Badly.  I recommend a heavy dose of Advil after reading it.  You'll need it.
  • Use one of these algorithms.  I do prefer Rijndael/AES, but any of these (even DES) is better than creating your own "crypto algorithm".  In the words of Michael Howard, that's craptography.  Just say no.  Don't do it.  Unless you are a PhD in Mathematics specializing in crypto algorithms, you'll get it wrong. Read the Rijndael article referenced above. If you can't understand it ... don't write your own algorithm.  It's just that simple.  Even if you do understand it, it's still not a good idea to write your own algorithm.  Just use Rijndael. It's been well vetted and just because the algorithm is known doesn't mean that it's less secure.  On characteric of a good algorithm is that the algorithm details can be public without compromising the security of the algorithm.


Tags: , ,

.NET Stuff | Security

Forays into LSL ...

December 30, 2007 1:37 PM

I've made my first foray into LSL ... the Linden Scripting Language.  This is the scripting language used by Second Life to do ... well ... all kinds of things with stuff in SL.  After spending some time playing with it and even more time fighting it, here's my own personal point of view.  Keep in mind, too, that this is coming from someone that's been working with the most advanced code editors in the world for many years ... these being the different version of Visual Studio (no, not Eclipse ... they copied).

OK ... LSL is pretty flexible.  You can do some interesting things in-world with it.  If you look around Second Life, this is pretty obvious ... there are a lot of things that are scripted in there.  And it really does add to and enhance the experience.  Things like particle systems, bling, payment and vendor systems ... basically anything that does more than just sit there ... is based on LSL scripts.  It's very similar, structurally to C and C-derived languages such as C++, C#, Java and JavaScript, so if you already know these languages, you have a leg up. 

That said ... well ... let's see ... where to start.  I'll start with the most basic thing that a developer needs for any environment.  No, it's not an editor, it's documentation!!!  The official documentation for LSL is on the Second Life wiki's LSL Portal (http://wiki.secondlife.com/wiki/LSL_Portal).  Finding this, at first, was something of a challenge.  You have to know that it's part of the wiki ... there is no self-evident link (that I could find which, of course, means that it's not self-evident in my little world) on the Second Life home page or in-world. Now ... I do think that wikis are an awesome way to disseminate information and get feedback (MSDN has done a great job with this), but I do think that there should be complete documentation provided by the vendor, with wiki functionality as an enhancement. If you look at the wiki, there is even a list of functions that need examples.  Can you imagine if Microsoft did this with .NET?  People complain about out documentation all the time (and I agree ... it could be much better), but it is worlds better than the LSL docs and, in fact, a lot of the other documentation that I've seen out there. There is an alternative documentation effort as well (and why is that?) at http://www.lslwiki.net/lslwiki/wakka.php?wakka=HomePage which, it seems to me, is a bit more useful. 

Now ... the in-world editor.  Oh boy.  Reminds me of the VB4 editor ... color coding but that's it. It is very lacking in some of the basic features that modern developers have come to expect in a code editor (regardless of their choice of editor).  There is no Intellisense, no argument help, which results in constant flipping back and forth between the editor and the documentation.  There is a combo box in the editor that lists all of the built-in functions and constants and will insert these, so that's helpful.  However, I was expecting that a function gets inserted with argument placeholders ... this would seem to be easy to do (certainly easier than Intellisense) and make it a little more intuitive.  The development involved to do that would be no different from what they are already doing with this combo box, so I'm somewhat baffled as to why it's not there.  Yes, there are separate editors, but most lack a runtime environment and even those that do, the runtime debugging environment is merely an approximation of the real SL runtime.  And then there's the quandery of taking the externally edited scripts and bringing them in-world. 

Closely related to the editor (at least in my mind) is the debugger (after all, it's the editor that you use for debugging, right?).  Ummmm ... what debugger?  Seriously ... what debugger?  There is no in-world debugger.  Yes, there is a test harness posted on the LSL wiki, but it's not really an interactive debugger. Debugging your scripts involves the stuff that we used to do in ASP "Classic" (even with InterDev 6, debugging ASP Classic was something of a challenge at times). So ... yes, just like Response.WriteLine().  Except ... you have to use a dialog channel for it.  Fortunately, there is a debugging dialog channel that goes into the Script Error/Warning Window. But peppering these calls throughout your code?  Ugggh.  Of course, just like in ASP Classic, I wrapped this in a function ...

sendDebugMessage(string message)
{
    llSay(DEBUG_CHANNEL, llGetObjectDesc() + ": " + message);
}
everywhere) with on line commented out. You'll also notice in there the "ll" before every function call. All of the LSL functions are prefixed with "ll". Most of the functions have names that are very obvious about what they do, which does make the code somewhat easier to read.  But they are quite limited in scope (about 300 functions in all, I believe) and there are some functions that I would expect in there that aren't.  There is, in fact, a section on the LSL Wiki that lists a function wish list (see http://wiki.secondlife.com/wiki/LSL_Useful_Function_WishList).

Now, one of the very interesting things about LSL that I saw was that each script is actually state-driven.  I can't say it's quite a full state-machine, but it is state-oriented.  (Think VB 6 ... not object-oriented, but it was object-centric)  Each script must have a default state, but also can have a number of other states, depending on what you want to do.  Each state will have its own event handlers for LSL events and there is an LSL function that allows you to change states.  This may initially be somewhat alien to traditional MS developers, but it's pretty easy to pick up.  And if you are familiar with Windows Workflow Foundation, it'll be very obvious (even if you feel it's limited compared to WF). So ... state driven with events.  Object oriented?  Not even close.  VB6 was closer to being object-oriented.  Arrays (or Lists in the LSL type system) aren't even directly accessible but must be handled using a whole set of LSL functions specifically for manipulating them. You can run multiple scripts in an object ... in fact, all scripts contained in an object will run simultaneously and can be in different states at any one point in time.  This does make for some interesting possibilities as well ... though it can pose some challenges if, for  some reason, you need to synchronize states between the different scripts.  Which brings be to reusability and componentization.  These are core concepts of programming languages that date back to ... what?  the Stone Age?  Yet, in LSL, this is quite challenging ... there is no direct way to reuse scripts in multiple objects.  Instead, you have to create a link channel that allows communication between them. Linked messages allow scripts in multiple prims in the same object to communicate ... or separate scripts in the same prim to communicate.  This is, in fact, mentioned quite directly in the official LSL wiki:
Using llMessageLinked in a single prim object allows developers to mitigate some LSL limits by breaking up functionality between cooperating scripts and synchronizing actions. When you do this, be extremely careful not to create infinite loops as mentioned above.
It does strike me as a somewhat inelegant way to accomplish this. I can see the need for it, I suppose, between multiple scripts in separate prims, but between scripts in the same prim?  I don't know ... slap me twice and call me silly (you wouldn't be the first, I can guarantee that!).

Wow ... looking over this, it looks like a major complaining and whining session.  OK ... well, it kinda is.  None of this means that I don't like Second Life and none of it means that I don't think that Second Life has huge potential as a new community and communication paradigm.  And the Lindens have done an outstanding job creating the world and a rich, immersive client.  There is, honestly, quite a lot of amazing stuff that they've put into SL.  It just occurs to me that the scripting environment may not be their strongest talent.  I have heard a rumor or two that they are looking to implement Mono in SL as a scripting language, which would take a great deal of the work off their plates.  I think it's a fantastic idea.  Some of you .NET purists may be frothing at the mouth ... "Why aren't they using the full .NET?  Why Mono?".  Well ... if you are one of them ... chill.  The reality is that the Lindens have to provide a client for Windows, Apple and Linux.  It's just a fact of their business.  The full, Microsoft-provided, .NET Framework doesn't run on 2 of the 3.  Mono runs on all three.  Should this happen (and I hope it does!), we'll get real OO and C#!

And now I'm off to dabble in LSL now.  Going to play with the XML-RPC (oh, how quaint!) and HTTP functions to start getting in-world scripts hooked up with .NET web applications running in the cloud.  That could be many levels of coolness!!



Tags: ,

Idle Babbling | Second Life

Second Life DNUG Presentation ...

December 22, 2007 7:23 PM

On January 9 at Noon SLT, I will be delivering a presentation on ASP.NET Performance Tips and Tricks.  I'll be covering some things are may be somewhat obvious, some things that are applicable to all .NET applications and finally, as most importantly, some tricks specifically for your ASP.NET applications.  I won't say much more 'cuz I don't want to spoil the fun.  But I will say that there are a couple of tricks that will knock your socks off.  So ... if you're in Second Life, come join us at the Microsoft Island.

For more info, see the Second Life .NET User Group web site at www.sldnug.net



Tags: ,

Events | Second Life

Thoughts on "We Are Microsoft"

December 20, 2007 4:16 AM

There is an initiative here in South Central that we are working on called "We Are Microsoft".  What is it?  Well, we're collecting charities that need help with coding issues and developers that, well, write code (duh!) and matching them together.  Over a weekend, the coders will build solutions to help these charities do their important work.  It's a beautiful thing, but more on that in a minute. 

I had a conversation with Toi Wright today ... she's the user group leader that's really doing all of the leg work to make this happen.  (Thanks Toi!!!  You rock!!!) We got to talking not about what we hope that the charities would get from it (that was pretty clear), but what the developers would get out of it.  That feeling, that sense, deep in their soul (and this is very hard to describe in words) that they have made a difference, however small, and helped make the world a little better.  OK, those weren't the exact words, but that was the gist of it.  As developers, we tend to love what we do.  We love going in there, day after day, sitting in front of a computer screen and slinging code.  We love solving problems, the tougher the better.  That's just how we are.  We put a piece of ourselves in every line of code that we write.  But to what end?  To solve a business problem?  To improve efficiency?  To maximize profits?  I'm not saying that these are bad things ... I am a staunch capitalist to my core ... but are they making the world a better place?  Do we walk out of the office with that deep singularly human feeling that we've made a difference in something that is greater than ourselves?  (Yeah, I'm showing the Lit major/poetry reader/sappy romantic side of me ... deal).  I can tell you from experience that the answer is no.  Yeah, we may console ourselves that we help people get to their families earlier ... but that's a stretch. 

But that's really not what this conversation with Toi made me think about.  Not at all.  Nope.  It made me think about the project that is, to this day, the best and most important project that I've ever been on. And I've been on some big projects ... like multi-billion dollar eCommerce projects and such ... but none of them hold a candle to this.  I mentioned it to Toi and, even now, two years later, it still brings up something up in my heart and soul that defies explanation.  This project made absolutely no money whatsoever.  But it helped people.  In a very real way. It made a difference in their lives.  It was, and still is, bigger than any of us on that team.  For those of you that read my blog back then, you'll know that this was KatrinaSafe ... which is now the Red Cross' Safe and Well web site.  We built it to help bring families back together after the worst disaster in American history.  I remember well the day we got our first positive matches ... matching people with family members that they lost track of in the ... confusion?  Well, for lack of a better word, that works. We celebrated. We jumped for joy. What we were doing was beginning to show the results that we were hoping for. We then started getting emails about how we helped people ... what it meant to them. One I remember well is from a mother who was separated from her children in the buses out of New Orleans. She was worried sick. She found them, and where they were, on the site. She spent the next two days getting there, doing whatever it took. Grown men wept hearing this email. There was not a dry eye in the place.

Oh, yeah, and lest I forget to mention, we had sponsorship from "On High" at Microsoft.  At the very, very, very highest levels. Up in the stratosphere. It made me proud and humbled to work for a company that would do as much as it could.  Not to make money ... it wasn't about making money (the PR didn't come out until months later).  It was about doing what's right and money was no object (that is almost unheard of at MS ... we do have budgets). Microsoft is very cool that way. We will step up to the plate and do what needs to be done. It's part of our culture.

I was fortunate to be in the right place, at the right time, to be a part of that. It was truly a blessing. Never in my life have I been so happy to work 18 hour days (we did). I imagine I'll tell my grandchildren about it. It is that important to me. Yeah, there was a cool eWeek article about it, but that's not what matters. Even without that, I'd feel no different. It wasn't gravy ... it wasn't the icing on the cake ... it was a side dish that you could do without but ate anyway. (And I'll never tell the entire story behind that article!!)

This is the most important part!

This is what we are trying to give developers here.  The chance to be something bigger than themselves.  The chance to touch people's lives, to know that they made a difference. To look back years later and say "Hey, I really did something important here."  It's a rare opportunity.  I'll be there.  Wouldn't miss it.  I know how it feels afterwards. I know what it means. You can't put a price tag on that.  It's happening in Dallas, so if you're in Dallas, you have no excuse. Those of you in Austin, Houston, San Antonio ... you're a drive away from Dallas.  Why not drive up there for the weekend?  I can guarantee it'll be worth the gas.  Also ... for those of you not in Dallas, if you want to do this in your city, for charities and groups local to you, leave a comment here. I can't make any promises ... but we'll try. Let me know where you are and I'll make sure that the DPE folks in your area hear about it. And, if it's in my area (South TX, LA) or my buddy Chris Koenig's area (North TX, OK and AR), we'll do everything we can to make it happen. That I can promise. This is a program that should be nationwide.  Heck, it should be worldwide. (Think globally, act locally) There are folks working hard to make the world a better place out there.  We, as developers, have the skills and the talent to help make that happen. This is better, this is more, than just donating money.  This is giving a piece of your heart and soul. And, I gotta tell ya, it gives you warm and fuzzies all over inside. And that is a Good Thingtm.

So ... no more sappy stuff for now.  Signing out.  Happy Holidays to all ... this is, after all, a season of giving, right? 

The answer is 42.  What is the question?  (Sorry ... too serious for too long ... had to do something ...)



Tags: ,

Events | Idle Babbling

.NET Framework 3.5 in Second Life

December 19, 2007 3:38 PM

Just got back from a presentation that my buddy Zain delivered in Second Life (where he is known as CSharp Writer) on Microsoft Island.  It was, in short, awesome!  The feedback from the folks that attended and the excitement was incredible ... watching the local chatter going on while Zain was talking, I saw many "Cool!"  "Wow!" "Awesome!" comments going back and forth, as well as many folks sharing what they thought were the coolest things.  There were a bunch of new .NET developers there as well ... probably getting their first exposure to VS 2008, Framework 3.5 and (maybe) even some Microsoft folks.  And then there were the community volunteers that helped make this happen ... G2 Proto, Tori Lukas and Blogland Oh ... and if I forgot anyone (and I'm sure that I did), please forgive me. 

It was interesting to do a presentation in-world, but it went very well.  Audio worked just fine and the slide show rezzed pretty quickly.  What I thought was most interesting was the chatter ... in a real-world meeting, this is extremely distracting ... in-world, it added so much to the presentation.  It's a very different environment; the attendees to the presentation had avatars ranging from robots to foxes to elves (me) and just about anything else that you can imagine.  You really get a feel and sense for someone in-world that you just can't get in RL (that's Real Life, as opposed to Second Life). Zain, the professional that he is, actually looked human.  It was also exciting to feel the buzz going through the in-world community. 

So ... some links that were mentioned during the presentation:
Live Meeting Install: http://go.microsoft.com/fwlink/?LinkId=90703 (we'll be using this for demos in the future)
.NET Framework 3.5 Poster: http://www.microsoft.com/downloads/details.aspx?FamilyID=7B645F3A-6D22-4548-A0D8-C2A27E1917F8&displaylang=en
Definition of Rijndael/AES: http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf (If you understand this, I hear that the NSA is hiring ...) Wikipedia also has a good entry on AES (that is somewhat more understandable) here: http://en.wikipedia.org/wiki/Rijndael



Tags: ,

.NET Stuff | Second Life