Showing posts with label Encryption. Show all posts
Showing posts with label Encryption. Show all posts

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

or:

<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:


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

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:


<configProtectedData>
  <providers>
  <add keyContainerName="SecurityKeys"
    useMachineContainer="false"
    description="Uses RsaCryptoServiceProvider to encrypt and decrypt"
    name="AppEncryptionProvider"
    type="System.Configuration.RsaProtectedConfigurationProvider,
    System.Configuration, 
    Version=2.0.0.0, 
    Culture=neutral, 
    PublicKeyToken=b03f5f7f11d50a3a" />
  </providers>
</configProtectedData>

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!

Tuesday, July 27, 2010

Solving a "The section is marked as being protected..." Error When Decrypting a .config With aspnet_regiis.exe tool

If you use the aspnet_regiis tool to encrypt sections of a .config file then you are ahead of the game is securing sensitive information with the apps configuration. If you have not used it before, I suggest trying it out sometime. However recently I came across an error while decrypting the 'appSettings' section that was as follows:

"The section is marked as being protected, but it does not have the correct format. It should contain only the <EncryptedData> child node."

It turns out that a new key that was auto generated in this particular project dealing with WCF was injected between the <EncryptedData> nodes (as shown below).

</CipherData>
<add key="ClientSettingsProvider.ServiceUri" value="" />
</EncryptedData>
Once I removed the new key and attempted the decryption, everything worked properly! So if you come across this error, see if any new keys have been added (or any other elements for that matter) between the <EncryptedData> nodes because it will cause this error.

Saturday, January 30, 2010

How To: Set Up BitLocker Full Disk Encryption + Pre-Boot Pin in Windows 7 Ultimate

Ok, this goes in the "and Beyond..." category because this post is not specific to .NET, but about setting up full disk encryption using a product by Microsoft named BitLocker. BitLocker is included is some of the premium Windows Vista and Windows 7 editions; specifically this post speaks of how to set up full disk encryption on Windows 7 Ultimate Edition.

There are several reasons for using full disk encryption; sometimes it is a requirement of the company you work for, or maybe you have sensitive information that needs to be secured in the event of your computer being lost or stolen. While traditionally you may think of using BitLocker just for laptops because of their portability which brings an increased risk of loss or theft, this could be done on a desktop with the appropriate hardware required as well.

I will preface these directions with some cautions and warnings. The process although not rocket science, is a series of steps that must be followed quite closely with no variations. I myself have had some unsuccessful attempts at setting up the encryption, which caused an OS failure, and the need to reformat and reinstall the OS again. That being said... "BACK UP EVERYTHING IMPORTANT BEFORE SETTING UP ENCRYPTION!" Ideally, you would do this initially upon getting a new laptop with Windows 7, or after doing a fresh install. That way if you run into any major issues, you can re-image the machine to its default configuration and start over again. I do believe that encryption overall makes the hard drive a tad bit more volatile, so regardless of the success of encrypting your disk, I recommend backing up important files from time to time after encryption is complete.

There are a few prerequisites to using BitLocker and full disk encryption. 1st, you need to have Administrative rights on the machine. The 2nd I already spoke of and that is needing Windows 7 Ultimate. The 3rd is a device that is imbedded in the laptop or machine called a TPM or "Trusted Platform Module". The TPM is responsible for generating and storing a keyset used for the drive encryption and for integrity checks of the system boot files. This results in securing the system volume with encryption and integrity checking the system boot files to ensure that nothing has been tampered with and the system drive is located in the original computer. Only then is decryption preformed. While there are software only solution for full drive encryption, they are more susceptible to hackers than BitLocker used with a TPM. Microsoft has published a wealth of detail on the underlying workings of BitLocker and the TPM, so I will not repeat it here. If you are interested, check out either of the following sites:

BitLocker Drive Encryption Team Blog

TechNet: BitLocker Drive Encryption


Alright now to the meat and potatoes of this project. Remember, try to follow each step as closely as possible without deviation for the nest results.

Step # 1: Backup all important files. Let me say again... Back up all important files. Just in case you have any issue with setting up BitLocker, you will not have lost all of your important data.

Step # 2: Update the BIOS for your machine to the most up to date version. Each motherboard or machine is going to have their own website for instructions and downloading and updating the BIOS. For example Dell has a site for its updates, ASUS has a site for their motherboard updates, etc. Oh, and if you are reading this and not sure what the BIOS is... I recommend to halt this procedure and not continue. Just my advice.

Step # 3: Log into Windows after the BIOS is updated and go to the following: Start -> Control Panel -> BitLocker Encryption. Find your Hard Drive and select "Turn BitLocker On". It should probably not work giving you the message below stating a TPM could not be found. If for some reason the BitLocker process begins because your TPM was already configured, should cancel the process and do the 2nd part of Step # 4: Configuring the boot sequence from the BIOS.


Step # 4: Enter the BIOS on boot and Enable the TPM and configure the boot sequence. 1st, enter the BIOS and find the TPM settings. They are probably under a 'Security' heading or something similar. All BIOS menus are different, so I don’t have the specific directions for each one, but navigate around until you find it. Once you do, select the option to enable it. 2nd, reconfigure the boot sequence. Make sure that any option for USB or Flash drives boot AFTER the Hard Drive. This sort of undocumented step caused me a lot of failed encryptions in later steps. The reason is that upon doing the BitLocker System Check, the system reboots and checks to make sure the generated keys placed on your USB Flash Drive actually work properly, prior to actually doing the encryption. Well if the USB is ordered to boot prior to the hard drive, the machine thinks you are using the USB as a boot device and forfeits the BitLocker check. You need to have the hard drive boot prior to the USB drive. No worries, though, if you ever need to boot from a DVD or flash, just go back in and switch the order to do whatever processing you need and then switch it back. Save your changes and exit the BIOS.

Step # 5: Set up BitLocker and the TPM. Log all the way back into Windows (do not shut down in-between) and go back to the BitLocker Encryption option in the Control Panel. Press "Turn On BitLocker" again. This time the BitLocker process will recognize a TPM enabled and being the process. You should see screens such as the following below:


Press 'Next' to begin BitLocker preparations:


Press 'Next' to begin the allocation of space for BitLocker:


Press 'Restart Now' and allow the machine to reboot as displayed below:


Upon logging back into Windows, BitLocker will continue the process automatically, so do not attempt to open anything else. You will see the screen below, and to continue the process press 'Next':


Upon completing the steps above, you will be prompted to reboot the computer so that the TPM can be configures. Press 'Restart' as directed. Upon rebooting, you will see a basic MS-DOS old school looking screen informing you that the TPM has been modified and do you want to allow the modification. Allow the modification and follow the directions to press the appropriate button. In my case I selected the 'Modify' (not the 'Ignore') so that the TPM configuration could be modified. Upon completion, the machine will reboot. Log all the way back into Windows. The BitLocker process will proceed automatically again. You should see a screen like below:


One the TPM hardware has been configured you will see a screen like below; press 'Next' to continue the process:


At this point you will be prompted to save off the recovery keys. These are the keys that are stored in the TPM, and are only needed in the event of system tampering or breech. I recommend doing all (3) options, and storing the keys to a USB drive, printing them off, and saving them off to a location OTHER THAN the system drive (secure network share, etc.). Obviously I should not need to explains too much here that the keys regardless of type (paper, USB, file) need to be locked away. Don’t leave the USB on the desk next to the laptop, or the paper with the keys folded under the machine. That is like leaving the keys to the car in the door lock. Continuing on...press each option in the screen below to save off the keys:


Step # 6: Run the BitLocker Check (USB with keys saved from Step # 5 required for this step). After saving the keys from above, press 'Next. You will see the screen below asking if you want to run the BitLocker check. While not required, I recommend doing it. You don't want to encrypt the drive until you have tested that the generated keys actually work. Check the box to run the BitLocker check and make sure that the USB drive IS INSERTED in the machine. Press 'Next' and the following reminder and reboot screens will be displayed:




Step # 7: Full drive encryption. Upon a successful reboot and USB keys check, the BitLocker process will automatically being the encryption process of the system volume. This will take several hours depending on the size of the drive, but you can continue to work in the background if needed. However, do not reboot or shut down during the encryption process. You can lock your machine if needed. The encryption dialog (shown below) will display the progress.


Step # 8: Configure the machine policy to require a pre boot PIN + TPM (Optional). Once the encryption is complete, you are technically done. The drive is encrypted and secure. You will notice upon reboot you are never prompted for the keys or a password. That's normal. The TPM has the keys, and if there was any breech or integrity failure, you would be prompted for the keys. Otherwise the authentication occurs in the background and is seamless.

However, to strengthen your security you may want to configure a pre boot PIN that works separately but in conjunction with the TPM. To accomplish this, follow Step # 8 and Step # 9 and Step # 10.

We need to open the Group Policy editor for the machine. Goto Start -> and type in gpedit.msc and press 'Enter'. Then Goto: Local Computer Policy > Computer Configuration > Administrative Templates > Windows Components > BitLocker Drive Encryption > Operating System Drives and right click the option "Require additional authentication at startup" and select "Edit". The screen is displayed below:


Select "Enabled" and then select "Require startup PIN with TPM" under the "Configure TPM startup PIN:" dropdown. Click "Apply, "OK" then close the dialog and Group Policy editor. This now allows us to configure the pre boot PIN from the command prompt.

Step # 9: Goto Start and type in cmd but do NOT press enter. Once the cmd application displays in the start menu, right click it and state "Run as Administrator". Click "Yes" on any security dialogs that may appear. To configure the pin we need to use the manage-bde.exe tool. To configure the PIN, enter the following and then press 'Enter':

manage-bde -protectors -add %systemdrive% -tpmandpin

You will be prompted to enter a PIN. (Note: I did notice if you still have the USB with the keys inserted into the machine, this process does not work - the command prompt never asks you to enter the PIN; make sure to remove it before doing this process). The PIN by default can only be numeric. There is an option in the group policy editor from Step # 7, to allow complex PINs for this process, but wars not all systems support it. Since you may not find that out until reboot, and not be able to log back in, I suggest just using a numeric PIN. You will be prompted to enter it twice, and upon success, see a screen like the one below:


Step # 10: Reboot and test the PIN. Upon rebooting, after the quick flash of your system manufacture screen, you should receive an old MS-DOS style screen prompting you for your PIN. It tells you the function keys can be used to represent numbers, but I always just use the keypad and it works fine. If needed, the option is there. Upon entering the correct PIN the machine will continue booting into Windows. One note on the pre-boot PIN: I have found that if you have your USB containing the keys inserted upon boot, it assumes you are validated and skips the prompting of the PIN. Since your USB drive should be locked away, you will be prompted for the PIN, but again, another nice option if needed.

And that is it! Hopefully your encryption process went well and you are complete at this point. I have done this process on 7 different machines with success, so I know it works when followed as directed. Your drive will now be secure with BitLocker.