Encrypting Credentials in App.config for Multiple Machines


We should all care as developers about security and how we store and use sensitive data, to either connect to databases, login to domain accounts etc.

Today I’m going to talk about how to encrypt usernames and passwords that are stored and saved to via an applications app.config. This article will use a custom configuration section called EncryptUserCredentials. I wont discuss how I created that here, but here is a sample app.config showing it, please not:

  • service: key value to the record.
  • userName: username.
  • password: password.

I will not show you the implementation details and how you would access this in code, until another post. Today i will talk about how you can encrypt the EncyptedUserCredentials themselves, because at the moment they are plain text for all to see!

The way you accomplish this is using aspnet_regiis.exe, which all you ASP.NET web developers will know registers your web applications with IIS.

But wait, there are other functions this fine and dandy binary brings and that is encrypting sections in web.configs…..

But I’m using an App.Config silly.

Thats right, that doesnt matter. They are just config files to .NET, but with different names. So let me explain what you need to do, but before that, here is where aspnet_regiis is located on your Windows box:

Version of .NET Framework Location of Aspnet_regiis.exe file
.NET Framework version 1 %windir%\.NET\Framework\v1.0.3705
.NET Framework version 1.1 %windir%\Microsoft.NET\Framework\v1.1.4322
.NET Framework version 2.0, version 3.0, and version 3.5 (32-bit systems) %windir%\Microsoft.NET\Framework\v2.0.50727
.NET Framework version 2.0, version 3.0, and version 3.5 (64-bit systems) %windir%\Microsoft.NET\Framework64\v2.0.50727
.NET Framework version 4 (32-bit systems) %windir%\Microsoft.NET\Framework\v4.0.30319
.NET Framework version 4 (64-bit systems) %windir%\Microsoft.NET\Framework64\v4.0.30319

Before we move on, I must tell you we are focusing on a multi-machine configuration file encryption using RSA. If though your application is running on one machine only then you can use DPAPI and its provider DataProtectionConfigurationProvider. DPAPI is handled by Windows itself and uses specific machine keys and containers. These are not transferable to different machines. If you wanted to use the DPAPI method for a multi-machine scenario, aspnet_regiis would need to be run on a app.config on each machine it is deployed on.

Why is that a bad thing?

Simple, you would need to store a plain text app.config file as either part of the Continous Integration process or someone would need to manually keep a copy and run it on each machine or even include the plain copy in the installer if that was your method for deploying. This just adds a security weak  point. You could include scripts to delete the plain text files, if this is the route you wanted to go down. But just so you know, DPAPI exists and could be a better option for you.

RSA route

So aspnet_regiis allows you to create containers of asymmetric private/public keys and export them to other machines, allowing you one global config file to be used.

Step 0 – Preperation is (RSA) key

Yes yes, Step 0 exits because I got half way and forgot this step, thank the stars it was meant to be Step1! Add a configProtectedData section to your config with provider. Please note:

  • keyContainerName – should be the name of the RSA container you will create later.
  • name – Can be anything. Im naming mine MyEncryptionProvider.

Step 1 -Espionage….

Yes i said aspnet_regiis wont have a problem with an App.config – it wont, but first you need to rename/copy said App.config file to web.config.

copy app.config web.config

Step 2 – Rise and Serve

Create a public/private RSA key pair with a specfic container name. They should also be marked as exportable (otherwise what is the point!). MyCustomKeys can be anyname you desire.

aspnet_regiis.exe  -pc MyCustomKeys -exp

Step 3 – Let me in!

Grant permissions for accounts to access the container. Example here is the network service say IIS uses.

aspnet_regiis.exe  -pa MyCustomKeys "NT AUTHORITY\NETWORK SERVICE"

Step 4 – Encrypt and Protect

Now the magic happens. The following line will now encrypt your section (my EncryptedUserCredentials are wrapped in section CustomConfg). The -pef switch is telling the application to look for a web.config file and to use my provider I declared in Step 0 (which is using type RsaProtectedConfigurationProvider).

aspnet_regiis.exe  -pef CustomConfig . -prov MyEncryptionProvider

You web.config file should now have transformed. Gone is the CustomConfig section with plain text credentials, now there is a nice CyperValues. Please note mine below have been replaced with hard coded text, but you will see what i mean when you do yours. Also note your CustomConfig section now declares it uses a configProtectionProvider=MyEncryptionProvider.

Step 5 – Export those Keys

So now we have created our web.config file you can rename it to app.config and use this in your application. To use it on different machines though, you will need to export the keys from the machine that you created the encrypted web/app.config file and import them onto each machine. Firstly on your machine run the following which will create the key file for your container, including the private keys (-pri).

aspnet_regiis.exe -px MyCustomKeys keys.xml -pri

Step 5 – Import those Keys

Log into the machine(s) you wish your application to work on and run the following

aspnet_regiis -pi MyCustomKeys keys.xml

I would do this as part of your Release or Installation process making sure you delete the keys.xml file from the installed machines. The only place the keys.xml should be kept is in your code repository store but somewhere safe where it is restricted. This is the security issue for the RSA approach.

 

The full encrypt and export script can be found here. Amend it to include your custom container, section and provider names.

 


  1. https://msdn.microsoft.com/en-us/library/k6h9cz8h.aspx

C# – CSV File Reader


 

CSV is a comma separated values file, which allows data to be saved in a table structured format. CSVs look like a garden-variety spreadsheet but with a .csv extension (Traditionally they take the form of a text file containing information separated by commas, hence the name).

 

At work, when taking on a new client and integrating them into our Distribution systems, we mostly write import routines to take in data and process it into our back office file system. We mainly receive these as flat CSV files – because these are easy to work with. Lets face it, the better way would be to expose some public API endpoints and provide these to clients to push data in a temporary data store (then for us to post-process it into our back office). We don’t. In an ideal world we would, but we live in a world of ideals which involve providing lots of different flat files and writing some custom code each and every time, mainly because we don’t have the time to write a more modular and reusable application….until now.

I will explore in my own time, how best to create a CSV Reader system using C# and how to process a file and validate it. Because there is no defacto standard, I have chosen to work with RFC4180 for the default behaviour.  I have just started this and the 1st version was pushed to github on Monday and can be found here:

 

http://garfbradaz.github.io/bradaz.utils/

 

Snip

 

 

 

 

 

I’m not going to explain all the code now as I would like to try a video tutorial at explaining each individual class, but the gist of it is in Bradaz.Utils.IO namespace includes:

 

  1. CSVRow – Represents a CSV File Row and tracks things like the row number and the original data. Also stores a collection of CSV Columns (CSVColumn).
  2. CSVColumn – Represents a CSV File Column and tracks thinks like the column and row number and the original data.
  3. CSVFile – This represents a CSV File itself with a collection of rows and a CSV File Reader (CSVReader) of buffered data.image
    The project itself contains some example code on how to load a test file, validate it (simple validation currently) and display the contents. Currently I only load into a string to view it:

http://pastebin.com/embed_iframe.php?i=Sj9A4MM2

 

I next want to enchance the Parser based on a XML configuration file that will allow a user to specify things like how many columns should be in the file and what types to expect in those columns and convert to a usable object, no more strings! (Things like dates and integers). More to come!

Strokes: achievements while programming! (via Timdams’s Blog)


This is an excellent piece of ingenuity. I will be checking this out soon!

Strokes: achievements while programming! Ok, so I’ve already hinted about this several posts before: an actual implementation of achievements-based programming in Visual Studio is being made as we speak. In this post I will humbly and proudly present the Strokes program that is rapidly evolving into something I’m eager to use in my own classes. Humbly because the work Jonas Swiatek has done is, in my opinion nearly epic, for each component in the project that I understand, there’s about … Read More

via Timdams’s Blog

[MVC 3] Image Preview–JQuery


UPDATE: I have now combined all my MVC Image Handling  blog posts into a Open Source Project. Feel free to check this out once you have read the post.

http://mvcimage.codeplex.com/

Original Blog Post:

At the moment I’m learning ASP.NET and MVC 3. Lets say I’m loving it at the moment, and at this present moment, I’m trying to employ my new skills in creating a new site for my friends friend, but i cannot disclose anymore on that….for now.

What i can disclose is snippets and code samples on my journey. Once such snippet is Image Previewing. Sounds easy, but as I’m new to this, it isn’t!

What I’m blogging about today and code I’m showing you is based on lots of articles i have read on the web. I’m one of those coders that cannot just Google + Copy & Paste, then move on to the next problem (to be resolved by the latter). I need to try and understand what the code is doing. So in the last week i have learnt:

  • JQuery and some JavaScript
  • A little more on how HTTP works behind the scenes using an awesome tool called Fiddler.
  • Specific browser requirements

Now before i move on, i have based my code on the following. Before this i was learning JQuery, so i wanted to amend the JavaScript portion to JQuery, but keeping the same concept:

http://weblogs.asp.net/imranbaloch/archive/2010/04/03/image-preview-in-asp-net-mvc.aspx

In addition my good friend and fellow Web Developer, Shaw Young, helped me with some tweaks! So thank you Imran for teaching me and Shaw for helping me!

Before i start discussing the JQuery, the following is the HTML that the code references.

        <input class="upload" type="file" name="imageLoad2" id="File1"/> <img alt="Preview" id="imgThumbnail2" height="26px" width="26px" /> 

So lets start from the beginning. I have created a JQuery script file, which is bound to the change JavaScript event, using the JQuery handler .change().

$(document).ready(function () {
  var inputTag = ".upload";
  var imgTag = "#imgThumbnail2";
  $(inputTag).change(function () {

I’m presuming you understand JQuery, but the .change() is hooking ANY input tags with the CSS class name of .upload and referencing any image tags with the id of  #imgThumbnail2 (which if you are using id, should be 1!).

Next we create a cloned image tag. We do this, because modern browsers will not allow you to copy the filename/directory values from one tag to another due to security reasons.  We then insert this cloned tag after the original .upload one.

NB: If you query the value in IE9 of the directory, you will be greeted with C:\Fakepath… now.

//-- Create a input attribute with the same type as the original //-- Insert it after the original's location. $('<input>').attr(
{
           class: "upload-clone",
           type: $(inputTag).attr('type'),
           name: "name-clone" }).insertAfter(inputTag);

Next we need to create a hidden form which we will post to one of our action methods Ajaxsubmit.

//--Create a hidden form with an action method pointer to //--our custom controller. $("<form>").attr(
{
           method: "post",
           id: "prototype",
           action: "/ImagePreview/AjaxSubmit" }).appendTo("body").hide();

We then need to change our new form’s encoding. Because different browsers behave differently, we change the attribute using the following.

//--Change the encoding based on the browser, as IE doesn't allow you to//--change the encoding. //--Append our original input to the hidden form. $('#prototype').attr((this.encoding ? 'encoding' : 'enctype'), 'multipart/form-data');

So we can submit the form and its contents, in this case the .upload input tag, we append it to the form, and hide it.

$(inputTag).appendTo("#prototype").hide();

We then use AJAX to submit the input .upload and its contents. Because we set the action method ImagePreview/Ajaxsubmit, this will be called, then the image tag will use the ImageLoad method. The first set is the JQuery and the 2nd is to re-iterate Imran’s method.

JQuery:

//--Use AJAX to post the form, and if successful, load the binary info the //--image tag. $('#prototype').ajaxSubmit(
        {
            success: function (responseText) {
                var d = new Date();

                $(imgTag)[0].src = "/ImagePreview/ImageLoad?a=" +                  d.getMilliseconds();

                $(inputTag).insertAfter('.upload-clone').show();

                $('.upload-clone').remove();
                $('#prototype').remove();

            }

        });

C# Action Methods:

public class ImagePreviewController : Controller {
    #region Ajax Submit
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult AjaxSubmit(int? id)
    {
        Session["ContentLength"] = Request.Files[0].ContentLength;
        Session["ContentType"] = Request.Files[0].ContentType;
        byte[] b = new byte[Request.Files[0].ContentLength];
        Request.Files[0].InputStream.Read(b, 0, Request.Files[0].ContentLength);
        Session["ContentStream"] = b;
        return Content(Request.Files[0].ContentType + ";" +         Request.Files[0].ContentLength);
    }
    #endregion #region ImageLoad
    public ActionResult ImageLoad(int? id)
    {
        byte[] b = (byte[])Session["ContentStream"];
        int length = (int)Session["ContentLength"];
        string type = (string)Session["ContentType"];
        Response.Buffer = true;
        Response.Charset = "";
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.ContentType = type;
        Response.BinaryWrite(b);
        Response.Flush();
        Response.End();
        Session["ContentLength"] = null;
        Session["ContentType"] = null;
        Session["ContentStream"] = null;
        return Content("");
    }
    #endregion }

So that’s it, with a little of JQuery magic, sprinkled with MVC goodness, we have an Image Previewing client side code, mixed with some AJAX.

I will try and get a solution up for people to use ASAP. In the meantime, if anyone needs it, let me know and i will email them the code.
Next up i will be:

  1. Adding some client side validation to make sure we are selecting image content types.
  2. Wiring up the JQuery to a HTML Helper using Razor for input file types.
  3. Create a T4 scaffolding template for input types to be re-used.