encrypting web.config in web farm - asp.net

I want to encrypt the connectionstrings in my web.config. And my application will be deployed in web farm.
I tried reading some blogs about this, but got confused.
Can somebody tell me a link which they have really tried and got succeded.

You may have considered this, but if not: the RSAProtectedConfigurationProvider can use either machine-level or user-level keys to encrypt. The default is machine-level. This means you can't encrypt your web.config once and deploy it to every machine in your web farm. You must encrypt it on each machine since the key to encrypt and decrypt only exists on that machine.
You can get around this problem by using a user-level key or sharing a key across all web farm machines:
Import/Export keys - http://msdn.microsoft.com/en-us/library/yxw286t2(VS.80).aspx
Machine-level verus user-level key containers - http://msdn.microsoft.com/en-us/library/f5cs0acs(VS.80).aspx

We use the RSA Protected Configuration provider. That page isn't light reading, but it's got what you need.
I recommend the command like so (example from the article):
aspnet_regiis.exe -pef "connectionStrings" C:\Projects\MachineRSA

Before encrypting the connection strings, think about what you are trying to protect against by encrypting them. Your application will need access to the cleartext connection string in order and therefore will need access to the key. Therefore, an attacker who compromises your ASP.Net application will likely be able to steal the key and your protected connection string. So encryption is not really adding much benefit.
Instead of encryption, focus on how that file is handled by operations personnel and the file permissions that are applied in production. Only allow Read access to the ASP.Net worker pool account that your application runs as.

Related

ASP.Net MVC 4 App: Best way to encrypt Web.Config files?

I was wondering what the best (most secure) way to encrypt Web.Config files in an ASP.Net MVC 4 Application are? I have some background with developing in-house applications using C#, but we never focused too much on encryption due to other security that was already in place.
EDIT: My host Server is ORACLE if that changes anything? A friend mentioned perhaps using aspnet_regiis.exe after deployment of my code with the '-pe' argument. Anyone have any pros/cons for this method?
EDIT2: ORACLE is a Database, not a Server! Can I go home yet?! >_<
The typical way is to use a ProtectedConfigurationProvider to encrypt the sensitive sections. There are several existing implementations. You can also implement your own if needed.
I was wondering what the best (most secure) way to encrypt Web.Config files
"Most secure" depends on what threats you are trying to protect against. You can assume that all the standard cryptographic algorithms are secure, but by encrypting web.config, you've simply exchanged the problem of protecting plaintext credentials in web.config for the problem of protecting an encryption key.
Typically you'll use Protected Configuration to encrypt web.config.
If you use the DPAPI provider, you'll encrypt using the server's machine key. This means that the encryption can be broken by anyone who can log in to the server. Also by anyone with write access to a folder containing a web site on the server, because they can upload code, say an aspx page with embedded script, that can do the decryption. This is a good choice if:
your server is secure (not shared with other untrusted applications, e.g. a hosting environment)
you don't want to copy the web.config to other servers (e.g. in a web farm) - it needs to be encrypted independently on each server.
Alternatively, if DPAPI doesn't meet your requirements, you should probably use the RSA provider. You can protect the key with an ACL against unauthorized access by other users on the same server, and can share it across multiple servers.
You can use the CryptoAPI to encrypt individual configuration values.
You can use the DPAPI to encrypt entire sections.

Encryption Web.config sections

I have read about aspnet_regiis for encrypting web.config sections in an ASP.net project, but I am confused how this works since the decryption key must live in plaintext on the actual server somewhere.
I would ideally like to use AES for encryption, but this requires adding the aes key to the web.config in plaintext itself, which seems useless to me. (from https://stackoverflow.com/a/8777147)
Perhaps I am missing something.. can someone explain how this encryption process is actually secure?
aspnet_regiis encryption is easy to decrypt if you are able to login to a session on the machine and have access to the key.
This protects against a scenario where someone can view the file but cannot login to the machine and a scenario where the decryption key is correctly ACL'ed to a known set of users.
Under the hood it uses DPAPI and machine context specific information. I believe you can also encrypt using a user profile in which case no other user can decrypt it.
Here are some useful links:
http://weblogs.asp.net/owscott/archive/2005/07/29/421063.aspx
http://weblogs.asp.net/scottgu/archive/2006/01/09/434893.aspx
You must create a key first and than use this key in your web.config
An detailed explanation can be found here: msdn microsoft
the one under web farm scenario's is the most practical.
I think it's useful to encrypt them if you have a lot of passwords etc. in the web.config.

encrypting web.config data for multiple servers

I need to encrypt sections of my web.config file for a client. Most of the references I've seen are to using aspnet_regiis to do the encryption. However, as far as I can see, this needs to happen on the web server which will host the site, which means the encrypted values will be different for each server. I don't have access to this client's servers. I found a passing reference to the possibility of encryping the web.config data in a way that is portable across servers, but haven't found any more detailed information. Does anyone know how to do this?
you need to encrypt it using RSA because with the RSAProtectedConfigurationProvider you could copy your key across server.
Web Farm Scenarios
You can use RSA encryption in Web farms, because you can export RSA keys. You need to do this if you encrypt data in a Web.config file prior to deploying it to other servers in a Web farm. In this case, the private key required to decrypt the data must be exported and deployed to the other servers.
Using the RSA Provider to Encrypt a Connection String in Web.config in a Web Farm
To do this, you must create a custom RSA encryption key container and deploy the same key container on all servers in your Web farm. This won't work by default because the default RSA encryption key, "NetFrameworkConfigurationKey", is different for each computer.
So, scrool down to the "Web Farm Scenarios" section of the above link and follow the steps.

What is the most secure way to connect a ASP.NET 3.5 web application and SQL Server database?

I have a web application developed in .net 3.5, and a SQL Server database.
Current auth method is a connection string in web.config, it seems like a good idea to move the authentication details out of plain text.
So, I have two questions:
Trusted Connection - The password policy here is strict, requiring frequent changes. Does this mean i'll have to update the password for the website every time it expires?
Is there another/better option?
As an alternative to trusted connection you can look at this set of articles on how to encrypt your web.config.
In brief, if you invoke from command-line
aspnet_regiis -pe "connectionStrings" -app "/SampleApplication" -prov "RsaProtectedConfigurationProvider"
section connectionStrings in the web.config of application SampleApplication from the default site will be encrypted using RSA.
I think putting the username/password is better simply because I don't want the user that runs my IIS server to have access to lots of databases. I would prefer to have it be focused, to where, for this application there is a user and that user has only access to this database.
You do need to be certain that your web.config file is secure, so you do need security on that.
If you want more security you could just use a dependency injection framework, and inject the compiled class that has the username/password, and just use that connection string. This class could be obfuscated, if you want some semblance of more security.
No, you won't have to keep changing the trusted connection details. You don't store the password there, so password changes won't affect you. (This is if you're using Basic Authentication, getting the users to connect to the SQL box as themselves)
But - if your application pool is running as a particular user, and that user has its password changed, you'll need to update that. You could consider having a user whose password doesn't expire for this.
Trusted connection isn't an option? A frequently changing password shouldn't be a limiting factor in your decision, since it's trusted you don't have to enter a password.
Another alternative is encrypting the connection string.

Using DPAPI / ProtectedData in a web farm environment with the User Store

I was wondering if anyone had successfully used DPAPI with a user store in a web farm enviroment?
Because our application is a recently converted from 1.1 to 2.0 ASP.NET app, we're using a custom wrapper which directly calls the CryptUnprotect methods. But this should be the same as the ProtectedData method available in the 2.0 framework.
Because we are operating in a web farm environment, we can't guarantee that the machine that did the encryption is going to be the one decrypting it. (Also because machine failures shouldn't destroy our encrypted data).
So what we have is a serviced component that runs in a service under a particular user account on each one of our web boxes. This user is a set up to have a roaming profile, as per the recomendation.
The problem we have is that info encrypted on one machine can not be decrypted on another, this fails with the win32 error:
'Key not valid for use in specified state'.
I suspect that this is because I've made a mistake by having the encryption service running as the user on multiple machines, hence keeping the user logged in on more than one machine at the same time.
If this is the problem, how are other using DPAPI with the User Store in a web farm environment?
In a web farm environment, rather than using DPAPI to encrypt/decrypt your data directly, you would instead use it to encrypt the key that you later use to decrypt your protected data.
You would "install" the key onto each server as part of the deployment process. The installation script would need to run under the AppPool's identity, and could store the encrypted key either in an app.config file or in the registry.
The encrypted data itself could be stored in a central repository / database, so that it can be accessed by all servers in the farm. To decrypt the data, the web app would retrieve the encrypted key from where it was installed, use DPAPI to decrypt it, then use the result to decrypt data that comes from the central repository.
The downside is that the cleartext key might exist on the local disk for a short time during the initial install process, where it might be exposed to operations staff. You could add an extra layer of encryption, such as with the web.config machineKey, if that's a concern.
The Microsoft poster is wrong.
http://support.microsoft.com/default.aspx?scid=kb;en-us;309408#6
"For DPAPI to work correctly when it uses roaming profiles, the domain user must only be logged on to a single computer in the domain. If the user wants to log on to a different computer that is in the domain, the user must log off the first computer before the user logs on to the second computer. If the user is logged on to multiple computers at the same time, it is likely that DPAPI will not be able to decrypt existing encrypted data correctly."
It appears that DPAPI will not work in a farm setting. I think this is a rather large oversight on Microsoft's part and makes DPAPI almost useless for most enterprise applications.
I just saw this. There is a way you can make this work, and that is to make sure the machines in the farm are in a domain, and use a domain account to encrypt and decrypt the data (ie; run the application under the domain account)
You cannot use DPAPI in the manner you want with local accounts because the key material is not exchanged between servers.
hope that helps!
Twelve years later . . . you can try using CNG DPAPI, which was meant to work in cloud environments that may or may not be load-balanced. From that link (in case it gets taken down):
Microsoft introduced the data protection application programming
interface (DPAPI) in Windows 2000. The API consists of two functions,
CryptProtectData and CryptUnprotectData. DPAPI is part of CryptoAPI
and was intended for developers who knew very little about using
cryptography. The two functions could be used to encrypt and decrypt
static data on a single computer.
Cloud computing, however, often requires that content encrypted on one
computer be decrypted on another. Therefore, beginning with Windows 8,
Microsoft extended the idea of using a relatively straightforward API
to encompass cloud scenarios. This new API, called DPAPI-NG, enables
you to securely share secrets (keys, passwords, key material) and
messages by protecting them to a set of principals that can be used to
unprotect them on different computers after proper authentication and
authorization.
In .NET Core this looks like
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection()
.ProtectKeysWithDpapiNG();
}

Resources