HOWTO: Use the aspnet_setreg utility to encrypt other values in the Web.Config

Here’s a slight hack I came up with to store encrypted connection strings in the registry that mimic the aspnet_setreg utility that comes with the .NET framework:

First you’ll run the aspnet_setreg command:

c:\> aspnet_setreg -k:Software\ASP.NET\MyKey -c:"data source=server;userid=user;password=password"

Please edit your configuration to contain the following:

sqlConnectionString = "registry:HKLM\Software\ASP.NET\MyKey\ASPNET_SETREG,sqlConnectionString"

The DACL on the registry key grants Full Control to System, Administrators, and Creator Owner.

If you have encrypted credentials for the <identity> configuration section, or a connection string for the <sessionstate> configuration section, ensure that the process identity hasRead access to the registry key. Furthermore, if you have configured IIS to access content on a UNC share, the account used to access the share will need Read access to the registry key. Regedt32.exe may be used to view/modify registry key permissions.

You may rename the registry subkey and registry value in order to prevent discovery.This command will create a Key in the registry here:

HKEY_LOCAL_MACHINE\Software\ASP.NET\MyKey\ASPNET_SETREG

Within that key it will create a Binary Value called “sqlConnectionString” set to the encrypted value of your connection string.

From here, I like to make one more modification:

Since I may not be storing a SQL Connection string, I’ll rename "sqlConnectionString" to something else more meaningful. For this example I’ll rename it to "customConnectionString"Next, I’ll add the following to my ‘web.config’

<appSettings>
<add key="ConnectionString" value="registry:HKLM\Software\ASP.NET\MyKey\ASPNET_SETREG,customConnectionString" />
</appSettings>

Next, I have written the following class which takes advantage of the NCrypto library to easily decrypt the connection string in the registry.
Imports Microsoft.Win32
Imports NCrypto.Security.Cryptography
Imports System.Text

Public Enum RegistryHive
HKLM
' HKEY_LOCAL_MACHINE
HKCR ' HKEY_CLASSES_ROOT
HKCU ' HKEY_CURRENT_USER
HKU ' HKEY_USERS
HKCC ' HKEY_CURRENT_CONFIG
End Enum

Public Class RegistryCryptoUtility
Private Const COLON_DELIMITER As String
= ":"
Private Const COMMA_DELIMITER As String
= ","
Private Const BACKSLASH_DELIMITER As String
= chr(92)
Private Const REGISTRY_PREFIX As String
= "registry:"

' Receives a string in the format:
' registry:HKLM\Software\ASP.NET\MyKey\ASPNET_SETREG,sqlConnectionString
' and pulls the value from the correct registry hive, and extracts and
' decrypts the connection string information
Public Shared Function DecryptRegistryConnectionString( _
ByVal configConnectionSetting As String _
) As String
Dim regKey As RegistryKey
Dim registryBytes As Byte()

If configConnectionSetting.StartsWith(REGISTRY_PREFIX) Then
Dim regKeyPathAndKey As String
= _
configConnectionSetting.Split(COLON_DELIMITER.ToCharArray())(
1)

Dim regKeyPath As String
= _
regKeyPathAndKey.Split(COMMA_DELIMITER.ToCharArray())(
0)

Dim keyName As String
= _
regKeyPathAndKey.Split(COMMA_DELIMITER.ToCharArray())(
1)

Dim regkeyHive As RegistryKey

' Open the proper Registry Hive
If regKeyPath.StartsWith( _
System.Enum.GetName(GetType(RegistryHive), RegistryHive.HKLM) _
) Then
regkeyHive
= Registry.LocalMachine
ElseIf regKeyPath.StartsWith( _
System.Enum.GetName(GetType(RegistryHive), RegistryHive.HKCR) _
) Then
regkeyHive
= Registry.ClassesRoot
ElseIf regKeyPath.StartsWith( _
System.Enum.GetName(GetType(RegistryHive), RegistryHive.HKCU) _
) Then
regkeyHive
= Registry.CurrentUser
ElseIf regKeyPath.StartsWith( _
System.Enum.GetName(GetType(RegistryHive), RegistryHive.HKU) _
) Then
regkeyHive
= Registry.Users
ElseIf regKeyPath.StartsWith( _
System.Enum.GetName(GetType(RegistryHive), RegistryHive.HKCC) _
) Then
regkeyHive
= Registry.Users
Else
Throw New ApplicationException(
"Unknown Key reference: " & _
regKeyPath)
End If

Dim seperatorPosition As Integer
= _
regKeyPath.IndexOf(BACKSLASH_DELIMITER,
0) + 1
regKeyPath
= regKeyPath.Substring( _
seperatorPosition, regKeyPath.Length
- seperatorPosition)
regKey
= regkeyHive.OpenSubKey(regKeyPath)
registryBytes
= CType(regKey.GetValue(keyName), Byte())

Return Encoding.Unicode.GetString( _
ProtectedData.Unprotect(registryBytes))
Else
' return the Config string, registry not specified
Return configConnectionSetting
End If
End Function
End Class

Finally, all that is left is to use the code above to extract the encrypted value from the connection string whenever you need it:


Dim connectionString As String = _
RegistryCryptoUtility.DecryptRegistryConnectionString(_
ConfigurationSettings.AppSettings()(
"ConnectionString"))

That's all there is to it.
References: How to use the ASP.NET utility to encrypt credentials and session state connection strings (Microsoft KB329290)

If you find this article helpful: kick it on DotNetKicks.com

0 comments: