Storing a Passphrase for SQL Server - asp.net

We have a web application that contains sensitive data. Currently we are using sql server 2008 and using DECRYPTBYPASSPHRASE and ENCRYPTBYPASSPHRASE for the sensitive columns.
The key was exposed and now they want to change the key.
The most important thing is what is the best practices for storing the pass phrase. The application is a asp.net connecting to a sql server 2008. The sql admins do not want it stored anywhere in the database. But then it will stored in the application server and will be transmitted over the wire.
Secondly, I don't like the fact that I have to decrypt then re-encrypt to change the key. Is there a better was of encrypting the sensitive data.
thanks in advance.

Related

How to best secure encryption keys for SQL Always Encrypted

Here's my requirement:
A database where at least 1 column on at least 1 table is sensitive, and should be encrypted
DBAs and people accessing the database with SSMS should not be able to view the plaintext values of the columns
There will be a client asp.net application that will be able to retrieve and decrypt the data, and insert and update to the table(s)
So, if I enable always encrypted on the necessary columns, any normal query will retrieve the ciphertext for those columns. Fine.
The client application will have Column Encryption Setting=Enabled on the connection string, so will have the ability to encrypt and decrypt data.
But what's to stop someone connecting with SSMS and enabling the same column encryption setting? They could then select from the table and see the plaintext.
In short, how do I apply permissions so that only people in a specific AD group, and excluding DBAs, has permissions to access the encryption keys to decrypt the data?
Is it as simple as making sure that the IIS that the .net application is on is not on the same server, and creating the column master key certificate only on that IIS machine?
There are two keys that are created Column Master Key (CMK) and Column Encryption Key (CEK).
The column master key is only stored on the application side, while the column encryption key will be stored on SQL Server side.
The result is that once the client has the CMK, you can activate encryption by changing the connection string and the driver will then look for this CMK. Without it the data cannot be decrypted.

Simple way to Encrypt Password Field in Legacy SQL Server Database

We have a legacy application that is storing the user's passwords down in the database unencrypted. We've had a fair few customers come onboard now which encrypting this password is a big deal to them (fair enough). Currently it's just a Nvarchar(100) field inside an SQL Server database table.
The situation is that we have multiple client applications accessing this database and validating against this password.
Just wanting to get advice on how we can achieve encryption on this field in the database without having to rewrite all the client applications that read off of it? It's not out of the question to change the client applications but we're trying to get away with this with as little fuss as possible.
Any ideas?
Do not do that, store salted, iterated HMACs of the passwords. Use something like Bcrypt, password_hash, PBKDF2 or similar.
If the HMAC is not salted and iterated it is not sufficient. Simply hashing without salting leaves the hashed passwords open to rainbow table attacks.
Convert the existing passwords now.

Best practice for passing actual user names from ASP.Net to SQL Server

I am looking for a best pratice to use the actual username in tSQL, while at the same time, my ASP.Net application logs into SQL Server with a global login, configured in the connection string in the web.config file.
This ASP.Net application is written as an extension to a SharePoint2007 implementation. The database this applies to is a legacy database, not a SharePoint database.
The application in question needs to log each insert, update and delete in audit (shadow) tables, including date&time and username. This is done by triggers.
The triggers use the SYSTEM_USER value, so that the global login is always written to the audit table.
There are about 2700 stored procedures in the system, and I guess that half of them perform DML statements.
What would be the best way to change the application so that the actual username is logged? My ASP.Net application knows the usernames. In fact, all of my users log in to the ASP.Net application with an Active Directory account.
I am considering the following options:
Use integrated security; but what about permissions that should only be granted throught the application, not to be used when connection with some other SQL client?
Set some global variable on each connection that is opened; but in the current code, each requests opens many connections, sometimes hundreds of them, to process the request.
Passing the username in the stored procedures, adding a field to each table. The trigger than simply reads the usernames from the tables in stead of deriving it; however, this requires a lot of modifications in database objects, potentially generating a lot of bugs.
Any comments on these options or perhaps other options to consider?
I normally use context info. Integrated security with impersonation will defeat connection pooling and passing username to procs just feels plain wrong.

Sending sensitive data from server to server via client

I have situation where I need to authenticate a client across multiple web services. Basically each service needs to identify the client and know a few other small pieces of information about the client.
The way I have it working now is that the needed identifying information is stored in a session table in a database by the authenticating web server. The web server hands the client an string, which IDs the database entry and gets passed to the other web services. The web services then use this string to pull the needed information about the client from the database entry.
It has occurred to me that it might be possible to give the client an encrypted blob that contains the user ID and other needed information, which is rather small, and avoid using the database for this completely. The client would just pass around the blob (like the string in the previous paragraph) without needing to know what it contains, and only the web services would know how to decrypt it.
This should eliminate the need for the database to store the session information and would make the whole process a good bit simpler. With the database you have to worry about cleaning up old sessions and timeouts and so on.
So my question: is passing around sensitive data from service to service via client considered safe and acceptable? Is it possible to do this in a way that would eliminate worry about the client tampering with the data? What encryption algorithms would be good to use? I'm using .Net - specific classes would be quite helpful.
That seems like a reasonable approach to simplify your app, but remember that if you use the client to store identifying data, you'll always be vulnerable to session hijacking attacks.
In other words, no matter how well you encrypt the blob, someone else can take the user's browser data and copy it, and impersonate the user. The ASP.Net session cookie is always vulnerable to this too, btw.
The only way to be completely secure is to use SSL.

Implementing application security - App Level & DB level (ASP .NET & SQL Server 08)

I am about to deploy an ASP .NET application (developed with LINQ-to-SQL).
I have taken following precautions:
Database access via user with limited access, however, since application is to access the sensitive data, I can't deprive this limited access user from it
Database server is not exposed to external network - is hiding behind DMZ and all external ports are blocked
I have done thorough security testing of the web-application; SQL Injections, rights management, illegal data access (via post/get data tempering)
Application is operating on SSL
Questions:
1 - I am using ASP .NET authorization API; any recommendation for avoiding session hijacking (in case someone some-how gets to know the session key). Is there are way to change the authentication cookie less prone to threats? Say like, changing it after every request? (I know I am get very conscious about this particular item)
2 - Data in the database is not encrypted. To make things ultra-secure, I am thinking about implementing transparent data encryption. Can someone share his/her experience or a link about implementing data level encryption with SQL Server 2008 along with pros-and-cons?
3 - Recommendation for storing connection string in web.config. Is using integrated security better then using encrypted database connection string?
It's seems to me that it's enough of standard asp.net api for this task. There is a very good article from MS P&P team about securing your forms authentication, it should help you.
I don't have such experience but here is a link with article.
I don't know :(
Also I recommend to check AntiXSS tool, it can show you some potential xss holes. And one last note, never trust to user input.
Integrated security is your strongest option.
I'm not an ASP.Net expert, but in my PHP projects I encrypt the cookie and affinitize it to a specific client IP. This way sessions cannot migrate to a different client. Ultimately, if you want to be absolutely sure, cannot rely on cookies for authentication, but instead use HTTP Digest, since browsers will transparently re-authenticate every request within the realm. Unfortunately this option does not work with the built-in ASP.Net membership providers as the HTTP Digest option they offer is half-brained to say the least (only authenticate against AD).
What specific threat are you trying to mitigate by encrypting data? TDE is designed to mitigate the threat of accidental media loss (ie. someone find an old disk of your with all the data on it, or you loose a laptop with the database on it). This is also the threat mitigate by most other database encryption schemes, like column encryption or file level encryption (bit locker). Other threats, like accidental compromise of access to the database (ie. someone finds a SQL injection vector to your db) cannot be mitigated by TDE, since the database will offer the decrypted data to any authenticated user. To mitigate such threats it means the data is encrypted with keys presented by the user (ie. only the user session can decryt the data becaus eonyl that session know the key password), but that knocks out the 'Transparent' aspect of all these encryption schemes. Having the user encrypt data with it's own key password protects data from other users (other sessions), so it is stronger, but its very difficult to 'get right', and the user is always at risk at locking himself out of its own data by forgetting/loosing the key password.
Use integrated security and store connection string encrypted. Since encrypting the strings in Web.Config is trivial and well supported in ASP deployment and operation, just do it. Encrypting the string protects agains accidental compromise of the IIS/ASP host from a non-admin account. An admin account, or the account under which the ASP runs will always be able to read the encrypted connection string. Since the most likely attack vector will always be ASP compromise (ie. SQL injection and friends) the attacker will most likely be able to read the connection string even when encrypted, so there isn't that much benefit from it, but every little bit counts.

Resources