Should I use RSAProtectedConfigurationProvider or My Own Provider? - asp.net

To encrypt web.config sections on both sites in a farm and single servers, from what I understand using the following command will encrypt my web.config connection strings using the local machine key
aspnet_regiis.exe -pef "connectionStrings" "C:\website\mywebsite"
However I could create my own keys using the -pc operator and use something like this:
<configProtectedData>
<providers>
<add name="MyProvider"
type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,
processorArchitecture=MSIL"
keyContainerName="MyKeys"
useMachineContainer="true" />
</providers>
What I don't understand is what is the difference? Is RSAProtectedConfigurationProvider less secure as its using the machine key and not possible to change? Should I use my own keys so I can change them? Which is the recommended solution for both a farm and single server? Or is there a better way to encrypt these sections without having to change or write any code?

For a single server you can reuse the key container installed by ASP.NET, if I'm not mistaken it's called NetFrameworkConfigurationKey, you just need to make sure that you give the account running your ASP.NET site the proper permissions to the key container.
For a Web Farm is better to create a custom key container in a machine and then export it to all other machines in the Web Farm, this way you can reuse the same encrypted config file saving you the time to encrypt the file in each Web Farm machine. However, this is not mandatory, you can deploy an unencrypted configuration file and encrypt it in each machine using each machine ASP.NET default key container.
Also the question title is a little misleading, when it comes to encryption you should always use a well established library and not go the roll your own custom encryption logic, which is difficult and easy to get wrong.
In terms of using a custom key container or reusing the one installed by ASP.NET with the RsaProtectedConfigurationProvider there is no difference in terms of the level of security provided.

Related

How do I encrypt web.config connection strings during deployment from the command line, specifying the encryption provider?

I know I can do this to encrypt connection strings in a web site that is already deployed:
aspnet_regiis -pe connectionStrings
I can also encrypt connection strings in a web site before it is deployed by doing this:
aspnet_regiis -pef connectionStrings .\WebApplication1
I also know how to make my own RSA key, install it on several computers, and set up an encryption provider for that key, so I can encrypt it on one machine and publish it on another:
aspnet_regiis -pef connectionStrings .\WebApplication1 -prov MyProvider
I can even tell MSBuild to encrypt the connection strings for me during deployment by adding a line to the .pubxml file (https://msdn.microsoft.com/en-us/library/ee942158%28v=vs.110%29.aspx#encrypt_webconfig).
But what I really need to do is this:
create the web site source code and save it in source control with the connection strings decrypted;
build the web site, transforming the web.config file with web.debug.config or web.release.config;
encrypt the connection strings in the transformed web.config using my custom encryption provider;
and then publish it
all from an automated process. Note: I can't encrypt the connection strings first and then build the web site, because I have to transform the web.config file before encrypting it. I don't want to publish the web site first and then encrypt the connection strings, because I don't want the decrypted connection strings to be on the web server even for a brief time. I want to encrypt the connection strings during the deploy process, but with my own encryption provider. How can I do that? It's got to be possible. Any combination of msbuild commands, msdeploy commands, and .pubxml file settings would be acceptable.
I've tried searching for how to do this -- I really have -- but I can't find a comprehensive reference for msbuild.exe / msdeploy.exe / *.pubxml ANYWHERE. (That's a separate question.)

Azure site only works when running locally with remote database

I have a site that's running off windows azure and I have hooked up the database via a linked resource and it looks like the site should be using the database. I've also included the proper connection string in my web.config file.
When I run the website locally and use the azure database's connection string for my default connection, everything works and I've seen that updating data from my local machine is reflected in the remote database.
Whenever I try to access any page that makes database hits (ie, logging in or looking at the basic index (from scaffolded out views)), I get a 500 error. I tried turning on custom errors but the 500 error is all I get. I tried to debug it from my local machine but that didn't help at all since everything worked properly when running the site locally and connecting with the azure database.
I have also pulled down the web.config files and the web.configs on both sides are identical.
I figure that this has to do with a configuration issue, but I'm not sure what.
Is there maybe something I'd have to do with asp.net mvc 5 to make it work with windows azure? It looks like the .net framework is properly set on azure to .net 4.5. I'm guessing it has something to do with the fact that Azure just doesn't know it should be using the database supplied in the web.config.
Here are the web.config connection strings:
<add name="DefaultConnection" connectionString="Data Source=####.database.windows.net,1433;Initial Catalog=####_db;Persist Security Info=True;User ID=####;Password=####" providerName="System.Data.SqlClient" />
<add name="DefaultConnectionDeploy" connectionString="Data Source=####.database.windows.net;Initial Catalog=####_db;Persist Security Info=True;User ID=####;Password=####" providerName="System.Data.SqlClient" />
<add name="DefaultConnection_DatabasePublish" connectionString="Data Source=####.database.windows.net,1433;Initial Catalog=####_db;Persist Security Info=True;User ID=####;Password=####" providerName="System.Data.SqlClient" />
Windows Azure makes use of transforms to manage connection strings. The connection strings are merged in at runtime, and can be controlled from the configure tab on the Web Site management page. whenever you set up an Azure Database as a linked resource, it automatically configures the Azure Database server with firewall rules to allow connection from the web server, and adds a connection string. By using this connection string, naming it the same as the string used in development, it is not necessary to modify any code prior to deployment. If you don't set the Azure Database up as a linked resource, it is necessary to modify the firewall rules by hand, which doesn't play nicely with the scalability of Azure Websites, so it's not recommended.
As per Andrew-counts' suggestion, I went and checked out my EF migrations (after pulling down the Azure web.config file using the "Replace web.config from server" option so that I had the exact copy that the server is using. I then enabled custom errors. It turns out that the pages were failing to load because of an error that stated that the table dbo.AspNetRoles already exists.
It appeared as though it was trying to run the EF migrations despite the fact that the tables already existed. To remedy this, I decided to go and wipe out my current database (I had just setup the database today so no harm doing that) and then, from the package console in visual studio, ran the Update-Database script before deploying anything to the server. When I did that, it correctly added the records inside of the dbo.__MigrationHistory table. I then checked in my changes so that the visualstudio.com build I have connected to my solution would build and deploy to Azure. The problem persisted, but what I realized was that I need to disable the automatic build + deploy that I was using and instead use the right click + publish, since doing it from the visual studio build wasn't connecting to the azure database properly (it wasn't transforming the web.config). When I used the publish from within visual studio, the site worked like a charm.
Thank you for all your help

Failed to encrypt the section 'connectionStrings' using provider 'RsaProtectedConfigurationProvider

Failed to encrypt the section 'connectionStrings' using provider 'RsaProtectedCo
nfigurationProvider'. Error message from the provider: Object already exists.
I followed the guide in http://msdn.microsoft.com/en-us/library/2w117ede.aspx but in step 3 in To grant the ASP.NET identity access to the RSA key container, it says that my identity is my workgroup\username, I do not have impersonation in my web.config file though
I am encrypting web.config using my machine using asp_regiis, then using visual studio to debug then it came with this error
For using RsaProtectedConfigurationProvider you need to launch your Command prompt or Visual Studio as an Administrator.
For DataProtectionConfigurationProvider it is not required to run under Admin rights.
You can create your own provider using RsaProtectedConfigurationProvider to encrypt your web.xml without administrator privileges.
Create a key store:
aspnet_regiis -pc "MyKeyStore" -exp
Grant read access for any user:
aspnet_regiis -pa "MyKeyStore" "Domain/User"
Put a provider section in your web.config
<configProtectedData>
<providers>
<add name="MyRSAProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"keyContainerName="MyKeyStore"useMachineContainer="true" />
</providers>
</configProtectedData>
Encrypt your config sections:
aspnet_regiis -pef "configSection" "c:\pathToWebConf" -prov "MyRSAProvider"
Sources:
Create RSA key container and provider
Encrypt configuration
This happened on one of my servers whole trying to move web apps from the c drive to another drive.
Because I had encrypted the web.config section on drive C and moved it to another drive, it jammed up the provider causing it to fail to encrypt the section because it believes it already exists.
I'm still trying to fix it.

Web config setting for deployment

In my web.config file, I have a connection string to connect my development database.
<connectionStrings>
<add name="MembershipDB" connectionString="Data Source=DebugSQL;Initial Catalog=PortalAccess;Integrated Security=True;Application" providerName="System.Data.SqlClient"/>
When I publish the web site to my production server, I just change the Data Source name.
When I test it, then I switch it again, is it stupid?
This is quite a common approach and can work well.
Obviously you can run into problems if you get the details wrong while maintaining it by hand this way.
You could also have a look into web.config transformations: This is a way of writing a main web.config file and then writing separate files that change the original depending on the build configuration you run.
Some resources:
Related question on StackOverflow;
Asp.Net tutorial;
MSDN Video for VS 2010.

Connectionstring Encryption in MVC2 .NET 4.0 app

I have an MVC2 .NET 4.0 app, hosted on TFS 2008 (soon to be TFS 2010) that uses connection strings in web.config to connect to a database on another server. I need to encrypt these connection strings.
As I understand it, I can use aspnet_regiis.exe to encrypt the connectionstring portion of the web.config file, but I have to do it on the deployment machine because the encryption uses the machine name to generate the encryption key.
Now, it seems to me that this represents a problem - every time I deploy my code to the dev server won't it overwrite the web.config file, and need to be re-encrypted? This sort of manual process seems kludgy.
Is my understanding about needing to re-encrypt after deployment correct?
If so, is there some way to automate this process? I don't want to forget this or get a new team member who doesn't know the process and have the connectionstring exposed to the world.
web.config files aren't typically part of a deployment (though Visual Studio 2010 supports configuration file transforms in web application deployment projects). I wouldn't expect that you should be overwriting the web.config when you deploy (because the web.config is where you would place those things that are specific to that machine/environment.
So, encrypt it once, and then don't overwrite it, would be my advice.
Since that isn't available in your situation, it is possible to specify a key when encrypting, so that you can share the encrypted file between machines. By default, the command to encrypt uses the DPAPI to encrypt the section (which is tied to the machine) but you can also use RSA for encryption. More info is available on MSDN in Specifying a Protected Configuration Provider.

Resources