What is the best approach to secure winform data? In other words how to secure the data from hacking for winforms c# projects?
There is a winform project with 25-30 forms. It stores data to the access DB.
If i start writing encryption/decryption logic to all the forms its going to take much time.
Is there any .NET dll/technique which can auto-encnrypt/decrypt before storing DB?
Is there some efficient quick approach for this?
Thanks,
Karthick
As the comments have said, depends on what you're trying to secure.
If you're trying to secure access privileges, you could use Identity and Principals to determine thread based authentication, permissions and roles.
If you're storing sensitive strings in memory, use SecureString instead of a regular stings.
If you are referring to preventing someone from "cracking" your software, employ obfuscation software to hinder any would be attackers.
First you must define what area of security you are looking for, then it's just a matter of doing the research... or asking here!
So if I understand correctly you want the data encrypted when you put it into the database and decrypted when you get it out again?
Firstly it is important to know who you are protecting the data from. Other users of the app? External people that might get access to the physical machine?
you should also probably have your code structured so that all access to the database goes through a single data layer. Perhaps single class or group of classes that do all of the data access code. This would mean that adding encryption and decryption as data goes into and out of your database would not be needed for all of your forms.
On the encryption side of things, you need to determine what you will use as the keys to encrypt your data. The fastest, and probably easiest, way to encrypt the data is with DPAPI through the Protected Data class.
The protected data class would allow you to encrypt the data so that it can only be decrypted on the same machine it was encrypted on, and an aditional value can be given so that only your app or something else that knows the extra value can decrypt it.
Another alternative may be to encrypt the entire database, though I am not sure what support Access has for this. Using the Encrypted File System and File.Encrypt might work if Access does not have anything built in.
These may or may not work for your scenario, it really depends on who you are trying to stop and how long you need to protect the data for.
Related
What native technology exists to encrypt/decrypt a string in the database for reading into a single application?
Scenario:
I have a set of connection strings that I need to use to securely access a set of production servers, for a polling application. I would like to store those in a table in a database and pull them out as I need them via a service. That will give me the ability for a handful of users (with permissions) to edit/add those entries.
My target audience using this application are all developers, these are servers to monitor our production and staging environments for some specific SQL flaws that I may need to later fix. This is a devops application.
Knowing that my target audience is developers, and that these are production servers, I would like to "lock the door" to keep people from actively seeing the production passwords/useraccounts unless they need them (auditing purposes). I realize that a lock is only as good as the frame around the door, and is only to keep honest people and petty thieves out, and that anyone dedicated will eventually be able to get past whatever safeguards I try to set.
Problem:
What technology in C# exists to secure this information and still allow me to dynamically add/alter connection strings but still keeps the data in the database reasonably secure? I am willing to make some changes to a machine.config or the like, but I need to actively develop the application too, so would like if it could be done in either machine.config1 or web.config, to allow for local development before deployment to the devops servers.
I understand that some of my alternative suggestions are:
Use strong database passwords to keep people out
Use strong schema organization to keep people out
Trust the developers, they work for your org (see "audit trail". I need to make some stab at securing production credentials)
Don't let people have access to the server and store them in the web.config (already plan on this in the first place)
Ideally:
Ideally I would just use a private key for encryption/decryption on the application server, but I don't exactly know the most secure way to do this, other than base64. I know this is not encryption.
What technology exists in the .NET native stack to securely encrypt/decrypt a string that may contain special characters in a single application and what is an example usage of this technology?
If I knew a name and technique, I would not be asking this question.
1 using machine.config/web.config to indicate something inherent in the .NET stack. I'm open to any suggestions.
Saving connection information in a database table is going to be unsecure, always. At some point, you're going to have to decrypt the password, and send it to the server. Developers tend to be smart enough to figure out any "security by obscurity" approach, and get to the passwords at some point. Even if you encrypt the password in the DB (not too hard), as long as you pass it to the SqlConnection at some point, you still have to decrypt it somewhere on the user (developer) end.
Rather, the only way to do this securely, is to make sure the password actually never gets anywhere close to the developers (or anyone else). There's a few ways to handle this:
Use an external security provider, such as Windows authentication. This means you don't have to use any username or password at all.
Create some kind of a tunnel to send any required SQL. This is very easy if your developers only ever need to run SQL commands, and a bit trickier if they want to use productivity tools like Management Studio; however, even that's doable - SQL can run fine over TCP, and you should be able to emulate that quite easily. Only the tunneling server would have access to the actual credentials, your developers would only have credentials to the tunneling server (and limited ones at that).
Use the Linked servers feature. This allows you to link local users (your devs) to remote users (su on the target server or whatever). It should work just fine with all the usual security settings.
Out of these, I'd say linked servers might be the best. They're quite easy to use, they can be administrated by the select few, and they don't publish the password at all. You can also do queries that span servers this way - very handy for a maintenance tool :)
Windows authentication is incredibly useful, but usually only on LAN, since we're talking about having all the DB servers in a domain. VPN could help, but that's getting into complicated territory.
Using a tunnel isn't necessarily a bad idea, although I assume you'll run into a few issues before you get it working 100%. And in the end, that's what Linked servers do for you for free, so why not use that?
Now, if you really do want to go through with the encryption idea instead, you can pick from a plenty of .NET supported encryption schemes. AES should work fine - it's assymetrical, so knowing the encryption key doesn't mean you can decrypt the data (the decryption / private key should only be stored in a secure location and on the maintenance application server, in a place noone but the application itself can reach; do note that admins can reach anything, so if your people have administrator rights, this isn't going to work).
For an example, see the AesManaged class in System.Security.Cryptography - http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged(v=vs.110).aspx
Most applications only need one database, but you can use the Manager to create as many as you need. Multiple databases are independent of each other. If your application supports switching between multiple users, each with their own separate content and settings, you should consider using a database for each user. Otherwise, it's usually best to stick with one database.
So I'm working on a supplemental web-based system required by an HR department to store and search records of former personnel. I fought the requirement, but in the end it was handed down that the system has to both enable searching by full SSN, and retrieval of full SSN. My protestations aside, taking some steps to protect this data will actually be a huge improvement over what they are doing with it right now (you don't want to know).
I have been doing a lot of research, and I think I have come up with a reasonable plan -- but like all things crypto/security related there's an awful lot of complexity, and it's very easy to make a mistake. My rough plan is as follows:
On first time run of the application, generate a large random salt, and a 128bit AES key using RijndaelManaged
Write out both of these into a plaintext file for emergency recovery. This file will be stored offline in a secure physcial location. The application will check for the presence of the file, and scream warnings if it is still sitting there.
Store the salt and key securely somewhere. This is the part I don't have a great answer for. I was planning on using DPAPI -- but I don't know how secure it really is at the end of the day. Would I be better off just leaving it in plaintext and restricting filesystem access to the directory its stored in ?
When writing a record to the database, hash the SSN along with the large salt value above to generate a field that is searchable (but not recoverable without obtaining the salt and brute forcing all possible SSNs), and AES encrypt the raw SSN value with a new IV (stored alongside) to generate a field that is retrievable (with the key/iv) but not searchable (because encrypting the same SSN twice should yield different output).
When searching, just hash the search value with the same salt and look it up in the DB
When retrieving, decrypt the value from the DB using the AES key/iv
Other than needing a way to store the keys in a relatively secure way (number 3 above) it seems solid enough.
Things that won't work for us:
"Don't do any of this" Is not an option. This needs to be done, and if we don't do it they'll a) get mad at us and b) just pass all the numbers around in a plaintext document over email.
This will be internal to our network only, so we have that layer of protection at least on top of whatever is implemented here. And access to the application itself will be controlled by active directory.
Thank you for reading, and for any advice.
Update #1:
I realized from the comments that it makes no sense to keep a private IV for the SSN retrieval field. I updated the plan to properly generate a new IV for each record and store it alongside the encrypted value.
Update #2:
I'm removing the hardware stuff from my list of stuff we can't do. I did a bit of research, and it seems like that stuff is more accessible than I thought. Does making use of one of those USB security token things add meaningful security for key storage?
I've had to solve a similar problem recently and have decided to use an HMAC for the hashing. This would provide more security than a simple hash, especially as you can't salt the value (otherwise it wouldn't be searchable).
Then as you say, use AES with a random salt for the reversible encryption.
It maybe that you don't need to encrypt this data but I had no choice and this seemed like a reasonable solution.
My question on IT Security https://security.stackexchange.com/questions/39017/least-insecure-way-to-encrypt-a-field-in-the-database-so-that-it-can-still-be-in
With respect to key storage there are two methods you can use if you choose to store your AES key in the web.config. First method is to use DPAPI as you mentioned. This will encrypt your web.config application setting for that box. The other method you can use is via RSA key (check out this MSDN tutorial), this will encrypt your web.config just like DPAPI however you can use the RSA key on multiple boxes, so if the application is clustered then RSA key is better (just more complicated to setup).
As far as generating the key before you run your application not on the machine running the app this way there's no chance you're going to leave the text file in the directory. You should generate the key as follows.
Generate a random value using RngCryptoServiceProvider
Generate a random salt value using RngCryptoServiceProvider
Hash the two values with PBKDF2 (Rfc2898DeriveBytes)
The reason you use the key derivation method is it protects you in case RngCryptoServiceProvider was found to be insecure for some reason which happens with random number generators.
Use AES 256 instead of AES 128, reason is these algorithms are extremely fast anyway so get the higher security it's almost free. Also make sure you're using the algorithm in CBC or CTR mode (CTR is available in the BouncyCastle library).
Now this will not give your key absolute protection if someone were able to put up a aspx file in your directory. Because that file will become part of your application it would have access to your decrypted values including your key. The reason I'm mentioning this is your network and server security will have to be top notch, so I would highly recommend you work hand-in-hand with your network security team to ensure that nobody has access to that box except the parties in the HR department that need access (Firewall not Active directory). Do NOT make this application publically accessible from the internet in any way shape or form.
You also cannot trust your HR department, someone could become a victim of a social engineering attack and end up giving away their login thus destroying your security model. So in addition to working with your network team you should integrate a two factor authentication mechanism to get into the system, highly recommend going with an actual RSA key or something similar rather than implementing TOTP. This way even if someone from the dept gives away their password because they thought they were winning a free ipad, the attacker would still need a physical device to get into the application.
Log Everything, any time someone sees a SSN make sure to log it somewhere that will be part of a permanent record that's archived on a regular basis. This will allow you to mitigate quickly. I would also put limits on how many records a person can see in a particular time frame, this way you know if someone is mining data from within your application.
Create a SQL user specifically to access this table, do not let any other user have access to the table. This will ensure that only with a particular user id and password can you view the table data.
Before deploying to a production environment you should hire a penetration testing team to test the application and see what they can get, this will go a long way to harden the application from potential attackers, and they can give you great advice on how to harden the security of the application.
Create a new salt and IV for each record. If you need to dump the data into a report for some reason (hopefully without my SSN in it), you would be able to use the method you describe with the unique salt and IV. If you only need to search on an SSN, you could actually hash it instead of using a reversible encryption (more secure).
I think I read somewhere once that hashing a limited set of inputs gets you absolutely nothing. A quick google turned up this SO post with similar warnings:
Hashing SSNs and other limited-domain information
I must admit that I am also no security expert, but given that the possible number of inputs is much smaller than 10^9 which any decent hacker should be able to breeze through in a matter of hours, hashing a SSN seems like you are adding a small layer of annoyance rather than an actual security/difficulty barrier.
Rather than doing it this way, could you do something else? For example, SSN's only have value to an attacker if they can associate a name to a number (since anyone can enumerate out all numbers easily enough). In that case, could you encrypt the user id that the SSN links to in such a way that would be impractical to attack? I am assuming your employees table has some sort of ID, but maybe instead of that do a hash on their email or some sort of guid? That way, even if they do get your SSN data, they would not be able to tell which employee's it is until they managed to brute force that link.
Then again, that approach is also flawed since your company may not have that many employees total. At that point it would be a relatively simple matter of guessing and checking against a company directory to attain everything. No matter how you slice it, this security flaw is going to exist if SSN's must be stored with other identifying data.
I have just started developing a desktop application using C# and SQlite database (with sensitive information) that will be installed on any PC locally. I would like to store the database password and the sql commands somewhere safe. I have a some questions about this:
How much do you think is the SQlite database secure? I have read
that by adding the encryption the whole file is encrypted, even the
header. By How much do you think it is secure?
To store the password, there are a lot of choices (and some are maybe simple suggestions that I was thinking of):
a) Storing the password and the SQL commands in a dll file and obfuscating it. But has anyone tried before to crack this or searched for it using Olly Debugger for example?
b) Encrypting it in the app.config file, custom encryption. But I've read a couple a articles and the encrypting connection string seems to be crackable...
c) Putting the password in an XML file and encrypting it or maybe in a serialized file (But the encrypting will also be stored in a the source code and can be refracted).
If the application has been obfuscated and the database encrypted. Do you think there will be any performance issues?
Thank you.
You need to ask yourself what is it exactly that you are trying to protect against and what for. Anything you can do in a purely client-installed application, especially a managed one, can be cracked quite easily. Dongles are more crack-proof, but will not stop an experienced cracker if the payoff is large enough, and they are both expensive and a pain in the ass for users and distributors. The only reliable way to protect your application is to run sensitive parts of it on your own servers. In your case, the database could reside on your server, then you can give out individual passwords, check IP addresses, limit query rates to deter scraping etc.
OTOH if your sole object is to protect your database against casual interest by persons having little technical knowledge, any scheme for database encryption and any scheme for password storage more complicated than plain text in the configuration file will work just fine.
I'm new to C# and ASP.NET and I have to do a project now. It deals with confidential data of a firm's employees so it needs to be encrypted. I am not sure if I will be able to get through with my own encryption algorithm. If I use any existing algorithms, they said that I should find a foolproof way to store the key.
To be honest, I don't really understand the term "key" in encryption. I would like someone to brief about it and help me with how I should move forward with this project.
http://en.wikipedia.org/wiki/Key_%28cryptography%29
dunno, but maybe start there?
IMHO:
as already advised, don't cobble up your "own", use existing algorithms in the framework that have been tested extensively. Whatever weaknesses they may have will (likely) still be better than what you can cobble up on your own.
understand what needs to be encrypted which pretty much means at some point will need to be decrypted vs. data that needs to be hashed (one-way - e.g. passwords).
decide if you want this to happen on the application side or perhaps, if resources are available to you like SQL server (to store data), on the database side (discuss this with your DBA). You can do both encryption and hashing in SQL server alone.
on the application side, you can think about storing keys in your web.config and subsequently encrypting that section - just like the option to do so for your db connection strings (encrypting the connection section of web.config). This way even your keys aren't in plain text.
The first rule of cryptography - never use your own algorithm, unless you are a Ph.D. and several other Ph.D's are helping you, even then, use only after public auditing.
What they mean about storing the key is that it shouldn't be exposed anywhere - if an attacker can get the key, they can decrypt all data in the database. Currently, there are no known ways to do this. You can store the key in a file outside the website's root folder - this way either the server itself must be compromised, your app must be compromised (e.g. by making it display the "../../key.txt" file, thus descending below the webroot) or your app must be tricked into encrypting/decrypting the data transparently for the attacker (e.g. by having a bug that allows authentication bypass, thus allowing them to use your app to talk to the database).
For the last part of the question, use #Haxx's answer :)
which algorithm is prefered for hiding an important string into database using c# ?
ENCODING AND DECODING STRINGS WITH C#
mean i have some important data (they are not passwords) , so i want to change them in database!
also i need to reconvert them to normal mode for using in my web pages ?
how can i do this job ?
i know we can use md5 hash for passwords / but by doing this we can not reconvert them to normal mode!
so , should be another way for another data!
thanks in advance
best regards
It sounds like you simply want encryption. Depending on the scenario (who can read it vs who can write it) this could be symmetric or asymmetric. Just keep the keys outside the db.
Another option: assume access to the DB is secure; then you don't need to encrypt the data. You would, however encrypt the connection, and typically enable the encrypted storage options inside the database itself. So everything is encrypted, but invisibly to you as a caller.
SQL Server has an entire set of encryption commands. You can view them here:
http://msdn.microsoft.com/en-us/library/ms173744.aspx