Tuesday, July 22, 2014

Hey Developers - is it UI, UX, UI/UX or something else?

My recent venture into consulting has allowed me the privilege of working with a talented UX team. The interesting thing is I probably fell into a trap and misconception about their roles and responsibility like any other developer that has not worked with a group containing this specialization. I rack that up to lack of 1st hand experience, so I've appreciated the onboarding of more knowledge. While this may not be the 'perfect' account of the UX professional's world, it's hopefully at least insightful to the large community of developers in a similar position to me.

Recently on our company Yammer site I saw the following quote by my friend and colleague Anthony Handley:
STOP staying UX/UI. It's just UX.
This had me thinking to the previous times I had Googled Bing'd the phrases "UI vs UX" or "difference between UI and UX." These were turning up abstract and sometimes confusing explanations. One link I pulled up was probably the equivalent of a 30 page document! Is it that complex? Other descriptions would say stuff like "the bike is a UI and the user thinking about the purchase and the tire size is the UX..." OK strike 1 - awful explanations and I like metaphors and analogies typically. I still didn't get it.

I was beginning to notice it is taboo to say the wrong acronym. To me I had always called it 'UI'. I consulted with another talented UX colleague of mine, Mickey Moran-Diaz for some consultation and education recently to make sure I didn't say the wrong thing. The resulting information I think built my knowledge to a point where I have a better understanding. 

The UX is everything. The UI is only a couple of aspects of the UX. Simple enough so far? Good.

A document I found in my searches highlights this well: UX is not UI. Take a look at the document on that page - it details in a single page all of the aspects of UX vs. UI. Notice how UI is only 2 very fine details withing the broad scope which is UX. This aligns with my friend Anthony's comment - "It's just UX."

This got me to thinking - why all the defensiveness that I've seen from UX people? I started to suspect that these talented group of folks were having their jobs being belittled/simplified to wireframing textboxes (see my post on Pencil for those devs that work alone). I come to find out this was at least partially true, and hence the passion of the UX team behind defining and making an understanding of the vast world that is UX.

This unfortunate simplification of an industry or profession albeit wrong, is quite easy to do. Think about it. "An accountant just adds numbers." "A pharmacist just puts pills in a bottle." "Playing basketball is just a ball going back and forth on the court." All simplifications and not realizing the entirety which makes up those professions. As typical it's "more than meets the eye." UX is much more than just wireframing a design.

UX is a multitude of practices, procedures, research, design, thought, artistry, and many, many more things that make up a being a UX person or team. The document in the link I provided above lists many of those aspects: research, design, brainstorming, requirements, interviewing, prototyping, and the list goes further. The bottom line - don't simplify the UX profession as a group of individuals that produce wireframes for a 'UI' design.

I also found that a lot of this conversation revolves around the context for which it is used. When it comes to a individual professional, team, or practice - it is just UX. However, in the context of an application's architecture I was beginning to be afraid to even call the topmost layer in my app 'the UI layer' anymore wondering if that was incorrect. With a sigh of relief, it is not incorrect. When speaking in a technical sense and distinguishing layers it's acceptable to still label it as the UI/Presentation/Views/etc. layer. In this context, it has nothing to do with the UX process or team, but rather to a technical distinguishing of logical layers in building an application. Cool, I can still say UI layer!

My experience though is the reality of the situation revolves around the fact that there are a ton of developers out there in ratio to UX professionals. As for myself I never had the privilege of working with a UX specialist at any job I've held until currently. This to most organizations (unfortunately) is seen as a 'luxury' position in addition to being misunderstood slightly and therefore does not have a presence. It probably falls in line with positions like DBAs where many companies do not hire them either. Developers do everything and hence the natural ignorance around these specialized positions.

Hopefully if you get the opportunity to work with a UX professional or team you will now as a developer or IT professional have a brief insight into the vast realm of responsibilities and expertise those in this field entail. It absolutely is much more to be a UX professional than simply doing UI design.

Friday, July 11, 2014

Encrypting Configuration Sections In .NET

Please note before reading - while you might of found this solution from a search result and the post looks long and possibly intimidating - it is not! Once you familiarize yourself with the steps, the process becomes quite easy to duplicate per machine where required. Most of the post here is providing explanation of what's happening as opposed to the raw steps needed to preform the encryption/decryption.

I have about a half of dozen posts in 'draft' form partially done that I want to get off my plate, so in no particular order here is one I've had on the back burner for a while. I'll guide you through encrypting configuration sections in application .config files. Nothing cutting edge her, but still an important topic to cover.

This is applicable to any type of .config such as a web.config or an app.config file so that means it spreads the technology spectrum of ASP.NET, WinForms, WPF, Windows Services, etc.. I have not yet looked into the equivalent for Win8 Store Apps using LocalSettings or RoamingSettings, so for now this is applicable to the aforementioned that use .config files. Since the LocalSettings are buried in .dat files in the user's profile the need may not be as pressing as the .config files that reside in the virtual directory of a web site directly in the well known inetpub\wwwroot.

So often I'm reading through a book, magazine, or online article and I see the following:

<connectionStrings>... with no encryption


<appsettings>... with no encryption

OK I get it, the authors typically do not have the time or want to go into a major tangent to talk about securing these elements with encryption. However today that's exactly what I'm going to show you how to do. If for some reason you have not caught on yet, you do not want sensitive information that is displayed above in plain text. If the file is compromised (internally or externally in the wrong hands for 1 of 100 reasons) it's a good layer of protection against being able to read it directly without decryption. In any regard, you as a developer should ALWAYS be thinking about security and protecting any type of sensitive data as if it's your own.

The steps are really straight forward and the process is quite simple and repetitive once you get used to it. I recommend you make a cheat sheet of notes for encrypting and decrypting the configuration sections to aid you on an ongoing basis. Steps 1-2 below only have to be done 1 time. Steps 3-4 are only done 1 time per machine where decryption will take place. Steps 5-6 are the steps ongoing to encrypt and decrypt configuration sections when needed.

NOTE: All steps below must be done running the command line tool as an Administrator. If you do not do this you will get various errors when trying to create/export keys as well as with manipulating permissions.

1. Create a machine-level RSA Key Container (1 time step)

Let's being by talking about the default provider and why it will not suffice for encryption / decryption needs outside of a single machine. 

If you use the default RSAProtectedConfigurationProvider without specifying a a Custom RSA Key Container, the encryption/decryption will only work on the machine where the data is 1st encrypted. Obviously this solution is no good as you will more than likely develop a solution locally and publish/deploy to 1...n servers. In this scenario, you need to create a Custom RSA machine-level container key and export it to a file which can then be imported on the servers where the application will run. 

If you try and decrypt the .config file manually using the command line with the default provider on a secondary machine where the encryption was not done, you will receive the following error below. Also in your .NET application at runtime, you would get an error upon trying to access any of the settings that have been encrypted.

Also before we get started we need to be aware of some permission issues. To prevent the following error: "Creating RSA Key Container... The RSA key container could not be opened. Failed!" message upon creating a new key, you will 1st want to set up permissions on the following directory where the machine keys reside after being creating: 

C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys

This is the directory where the machine keys from the command line below get created and stored. The issue is, even as an administrator you may not have access to create and manipulate the keys by default. The easiest thing to do is allow the 'Administrators' group of the machine have 'Modify' permissions to this directory.

Right-click on the 'MachineKeys' directory and ensure the Administrators group has the proper access:

Now that the permissions are set, we can being the process of creating our container. To create a Custom RSA Container run the following command:

aspnet_regiis -pc "SecurityKeys" -exp 

Note: the -exp switch allows the keys to be exportable (next step)

You should see the following success message:

2. Exporting the Custom RSA Encryption Key (1 time step)

Note: If just running through these steps and you want to see how it all works on a single machine locally, you can skip Step #2 and #3 and come back later to export and import to additional machines.

We must export the newly created encryption key so it can then be imported on 1...n machines where our app will run. This way we know decryption will occur seamlessly once we deploy.

To export the custom RSA key container to a file run the following command:

aspnet_regiis -px "SecurityKeys" "C:\SecurityKeys.xml" -pri

Note: the -pri switch makes sure both the private and public keys are exported. This enables both encryption and decryption. Without the– switch, you would only be able to encrypt data with the exported key.

You should see the following success message below. Also note the .xml file created in the location you specified in the command.

3. Importing the Certificate (1 time step - per machine)

Next we must import the .xml file containing the RSA encryption key on the machine(s) where our app will be running. Obviously we do not need to import it on the current machine because we have already created it in the machine keys. However, you must copy that file to the servers/machines where the app will run and import it.

I would assume the PowerShell gurus could script or automate this process rather quickly across machines. I'll just show the command required.

To import the RSA Encryption Key, run the following command:

aspnet_regiis -pi "SecurityKeys" "C:\EncryptionTest\SecurityKeys.xml"

You should see the following success message:

NOTE: It is important to DELETE the .xml file containing the keys once they have been successfully imported. This way the keys don't fall into the wrong hands and get imported on a machine where not desired. You can always go back to the main machine and export again as needed.

4. Adding Permissions to the Certificate (1 time step - per machine)

The certificate we just created now needs to have the proper permissions added to it so decryption can happen at runtime automatically under the context the app is running. If you are running an ASP.NET app in IIS that will be NT Authority\NETWORK SERVICE. The list of users or groups that need to have permission depends on they type of app you are running. If it's a WinForms or WPF app, you might add a group like CompanyXYZ\MyAppUsers. If you get any type of runtime errors along the lines of:

Failed to decrypt using provider 'AppEncryptionProvider'. Error message from the provider: The RSA key container could not be opened.

...then come back to this section and make sure to grant access both to the key and at the MachineKey folder to the user context for which your app/service/etc. is running under.

First we need to add access to the key container itself. For this example we'll assume we are running a web application using ASP.NET. To add access to the container run the following command:

aspnet_regiis -pa "SecurityKeys" "NT Authority\NETWORK SERVICE"

You should see the following success massage:

Second, we need to go back to the directory from step #1 and add 'Read' permissions only to the same user. To recall that directory is as follows:

C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys

Right-click the 'MachineKeys' folder and grant just 'Read' access to 'NETWORK SERVICE' as follows:

5. Encrypting the Configuration Section

Now it's finally time to encrypt!! Copy the full path to the directory containing your web.config or app.config file. Notice this super secret I have in plain text that we want to encrypt:

    <add key="SuperSecretPassword" value="abc123" />

Note: This process uses the aspnet_regiis.exe tool and targets web.config files by default. However, this will still work for any type of app.config file as well. Just close any open instances of your app.config file in VS.NET and rename it temporaily to web.config for the encrypting process. Once complete, rename back to app.config and open back up in VS.NET. You will see the encryption still works perfectly.

Add the following configuration section above the and section in your web.config or app.config file. The name property will be the handle we will use for encrypting from the command line and not the key container name, so just remember this so as not to get confused:

  <add keyContainerName="SecurityKeys"
    description="Uses RsaCryptoServiceProvider to encrypt and decrypt"
    PublicKeyToken=b03f5f7f11d50a3a" />

Close any open .config file being targeted, and run the following command to encrypt the section sepecified. You can change the section to be encrypted as needed:

aspnet_regiis -pef "appSettings" "C:\EncryptionTest" -prov "AppEncryptionProvider"

The values after the -pef switch indicates the section to encrypt. The value after the -prov (provider) switch should be the value from the 'provider name' property we set in the config file above. You should see success messages like the ones below. I encrypted both the <appsettings> and <connectionstrings> sections:

Now open back up the web.config or app.config file and the sections are encrypted!

6. Decrypting the Configuration Section

Decrypting the file as we will see in step #7 happens automatically upon calling any settings in code, but obviously the resulting encrypted sections do not allow you to make changes. You may need to decrypt the .config file to get the sections in a state where changes can be made.

To decrypt the .config file, run the following command (note the provider switch is not needed):

aspnet_regiis -pdf "appSettings" "C:\EncryptionTest"

You should see the following success message:

Open the file back up and it should be decrypted so changes can be made.

7. Seeing it in action within the application

Guess what code you need to access the <appsettings> or <connectionstrings> values in code to ensure it gets decrypted properly? Nothing!! That's why this is so great, all of it was handled in the configuration by the configured provider and Key Container.

Look at the following line of code in action! It was decrypted on the fly seamlessly and no special coding was needed. That's nice!

This is a really simple way to add security to those elements that are sensitive in your configuration files. So instead of having your entire database connection string in plain text within your .config file, consider taking 2 minutes and encrypting it!