In my winforms application i am hashing the connection string in local level.
But here a couple of questions.
After my app decrypts the connection string, the connection string info is sent in clear text? And since my app is installed locally the man in the middle could be ANY user?
How can i protect the connection string, becides the "force encryption" option, which requires an extra certificate?
You have only a limited amount of approaches here with regard to keeping your connection string safe and secure.
One option, if your connection string is stored within a web.config or app.config file (for web and windows apps, respectively) you can encrypt the value. Here's a couple of links that detail how that can be done:
Encrypting Web.Config Values in ASP.NET 2.0
Encrypt Connection Strings in VS 2005 .config Files
Of course, as you quite rightly say, this may not achieve the security that you desire, since the application may well be running on the user's machine, and thus the app.config file (even in an encrypted state) and associated encryption/decryption keys will also be available on the user's machine. A knowledgeable and enterprising user could then gain access to your "plain-text" connection string.
IMHO, one of the best ways to prevent your users from seeing your database connection string is to never give it to them in the first place, encrypted or not. This would require that your windows forms application does not talk directly to a database (using a connection string), but rather would talk directly to (eg) a web service.
Of course, you'd give the windows form application a URL with which it could access the web service, but then usage of this web service would be restricted and controlled by only allowing access with a user specific username/password combination.
This way, you can host the web service (doesn't have to be a web service - it could be a remote application that your windows form's application would communicate with over .NET remoting or WCF) on a physically separate server/machine that you do have complete control over and protect this machine with perimeter security.
It would be the applications and services that you have running on this secure machine that have access to the database's connection string, and this connection string need never be divulged outside of the perimeter of this machine, thereby keeping it completely secure (assuming the aforementioned perimeter security is in place and is effective).
Of course, implementing all of this would almost certainly mean huge architectural changes to your application, which, depending upon the size and nature of your application, may or may not be worthwhile, however, the only way to truly secure your connection string from a user (or a user's machine) is to ensure that it is never available (in encrypted or decrypted form) to the user (or user's machine).
As soon as you put the connection string on the user's machine, even in an encrypted state, you need to give that same machine that ability to decrypt that encrypted connection string, and there is the weak link in the chain and the point at which (to a resourceful user) your plain-text connection string can be determined. You could off-load the decryption of the encrypted connection string to another (secure) machine, but that's just a variation of the previously mentioned client-server mechanism whereby the part that is kept secure (decryption key, connection string etc.) is performed on a different machine under your own secure control.
you can't protect the connection string. what you can do is connect via SSL secure channel.
This page in the MSDN describes how to implement SSL for the connection:
http://support.microsoft.com/kb/316898
And this one describes SQL Authentication (for ASP.NET):
http://msdn.microsoft.com/en-us/library/ff648340.aspx
It seems that you only really need to encrypt the username and password? In which case, Windows Authentication should be an option (although I often have problems getting it to work for me)
Related
So, I've been reading about security in relation to desktop applications and database servers. Previously when I've built applications that are linked to a database, I've taken the easy route and simply stored the connection string hard coded in the source code directly. This has worked since the binaries were not distributed to third parties. However, now I'm working on a project whose binaries are bound for third party use, and in this case the communication with the server becomes a security issue that I need to deal with.
Since it is a priority that there be no direct connection to the remote database from the client machine, I understand that a server/client database service is a good choice. In this case, the client machine sends requests using TCP to a server, which then processes the request using stored procedures and responds accordingly to the client.
My questions in relation to this are:
i. Would this setup be an advisable one, or are other setups of which I am unaware more advisable for the kind of project I am working on?
ii. How does one go about securing such a connection? I can easily set up an SSL connection to the server using a security certificate generated by OpenSSL, however I'm not sure whether this is the correct way of securing the connection for a desktop application, or whether this method is primarily used for HTTPS. And WHEN should one in general secure the connection (are there instances where this wouldn't matter, for instance if all I do is send booleans back and forth?)? Any good resources that discuss these issues? For instance, I have a lot of application installed on my Windows PC that are networked, but I don't see many of them installing a security certificate on my PC. What gives?
Full disclosure: I'm a C++ (hobbyist) programmer using Boost libraries for my network programming needs and OpenSSL for my SSL cryptography. However, I hope this can be answered without paying too much attention to these facts :)
Answers:
i. Having your application talk to a web service that then talks to the database is a better setup. This abstracts the database away from the clients (and therefore direct access from the internet).
ii. This depends on what the threats to your system are. If the data you are vending from the web service mentioned above is data that is not sensitive, and is not user specific (say an app that allows searching of public photo galleries, so your web service simply returns a result set with URLs) then you might be able to get by with simply using SSL. Other apps get around installing their own cert in a myriad of ways. They can either get a cert from a CA like verisign, so your computer already trusts it. Or they can deploy the public cert with the binary of their app, and handle it inside of their app (this is a form of certificate pinning).
ii part 2. If you need the clients to authenticate, for reasons of either wanting to make sure that not just anyone can use your web service, or to support a more advanced authorization model, then you would need to implement some sort of authentication. That would be a much bigger question to address.
Make sure you use CA-signed certificates, and not self-signed. You might also want to consider mutual authentication between your service and the database.
as you guys know that the Hardcoded coding in exe file can easily be seen through some Softwares (e.g. code reflector), I want to know whether how can I Hide my connection string having information of sql server username and password to connect to database in windows forms application from being seen through any code reflector so that any one else Except me may never be able to use my application without my permission.
As commented, you are better off using Integrated Security, however if you are targeting a SQL Server with say Mixed Mode Authentication you could use the Data Protection API to encrypt the connection string in the app.config. Here is a great article on the topic:
Protecting application secrets, such as database connection strings
and passwords, requires careful consideration of a number of pertinent
factors such as how sensitive the data is, who could gain access to
it, how to balance security, performance, and maintainability, and so
forth. This article explains the fundamentals of data protection and
compares a variety of techniques that can be used to protect
application settings. The author discusses what to avoid, such as
hiding keys in source code and the use of Local Security Authority. In
addition, he presents some effective solutions such as the Data
Protection API.
Safeguard Database Connection Strings and Other Sensitive Settings in Your Code
How To: Use DPAPI to Encrypt and Decrypt Data (C#/VB.NET)
My web application stores external website login/passwords for interaction with them. To interact with these websites I need to use the original password text, so storing just the hash in my database is not going to work.
How should I store these passwords?
Edit:
I am concerned if someone gets access to my server. If I use some kind of 2-way encryption and they have server access then they can just check how the passwords are decrypted in my backend code.
It seems to me that you want to store passwords in a similar fashion as Firefox and Chrome. So why not look at how they do it?
This is how Chrome does it:
http://www.switchonthecode.com/tutorials/how-google-chrome-stores-passwords
If you MUST do this, you should use a two-way encryption. There are a lot algorithms (ciphers) for this, but basically you encrypt your data with an encryption key, and use the same key for decrypting them again.
Choosing the right cipher depends on which are supported by the programming language of your choice, but examples are:
Blowfish
3DES
Skipjack
They come in different complexity and some are harder to crack than others. You should realize though, that no two-way encryption is safe from cracking, given enough time. So it all depends on, how sensitive these passwords are.
/Carsten
Decide what you are protecting them against. Options include (but are not limited to): Accidental disclosure, disclosure by you, disclosure in transmission, disclosure due to code error, disclosure due to physical theft of hardware, etc.
If this is a web application, and each user is storing his/her own set of passwords, then you might encrypt these passwords with their login password to your application. If this is an application that each user installs separately, and which keeps its own local database, you could have an optional master password (like Firefox does).
If you are just ensuring that the data is safe if the hardware is stolen, you might use a full disk encryption solution like TrueCrypt or PGP WDE, or Ubuntu, Debian, or Fedora's built-in approach, and require a PIN or password on every boot.
If you just care about secure transmission, have code to ensure that you use transport security, and don't worry about encrypting the data in your database.
I would go about this in the following way.
Protect data against hardware being stolen:
Use disc encryption as discussed in previous posts.
Protecting data if server is compromised (hacked):
I would use two different servers for this project, one worker server and one front server.
A) Worker server
This has the DB with passwords etc,
it also connects to other services.
To connect to worker server, users
can do it through an API. API should
have on function, insertUserData,
which allows userdata to be inserted,
API escaped all the input.
API uses
a DB user which only has input
privilegies on the userData table.
This would be the only way to contact
this server.
Only allow SSL
connections.
This server in turn runs chron jobs that connect to external services, pulls data from them and populate it's DB. Use a different DB with different user privileges.
This server runs another chron JOB which connects to the front server and pushes new data to front server.
Minimal amount of services running
Only SSH/SCP from your IP, tight firewalling. Block if connections exced X / min etc as they only would do an occasional insert.
NO FTP etc.
B) Front server
Receives data from Worker server, never uses the passwords itself. Only way to contact worker server is through API mentioned above, only for new user information. This is where all users login to see their information etc.
The problem with doing it all on the same server, if you get hacked the hacker can sit and sniff all incoming data / passwords etc.. so even if they are stored / encrypted / decrypted securely, with some patience he would sniff them all.
When the application is first run, it will generate a random key. This key will be used to encrypt and decrypt sensitive data. Store the key in a local file, and set the file permissions so that nobody else can read it. Ensure that the user running the web server has no login access (this is a good idea anyway).
Possible ways to break this system:
Get root access.
Get sudo access.
Deploy a malicious application on the web server - this application will then have access to the key, and may be able to send it elsewhere.
As long as you take reasonable precautions against all of these, you should be OK.
EDIT: Come to think of it, you could just store the sensitive data right in the key file. Encryption would provide an extra layer of security, but it wouldn't be a very strong layer; if an attacker gets access to the file, chances are good that he also has access to the DB.
I am trying to devise a security scheme for encrypting the application level data between a silverlight client, and a php webservice that I created. Since I am dealing with a public website the information I am pulling from the service is public, but the information I'm submitting to the webservice is not public. There is also a back end to the website for administration, so naturally all application data being pushed and pulled from the webservice to the silverlight administration back end must also be encrypted.
Silverlight does not support asymmetric encryption, which would work for the public website. Symmetric encryption would only work on the back end because users do not log in to the public website, so no password based keys could be derived. Still symmetric encryption would be great, but I cannot securely save the private key in the silverlight client. Because it would either have to be hardcoded or read from some kind of config file. None of that is considered secure. So... plan B.
My final alternative would be then to implement the Diffie-Hellman algorithm, which supports symmetric encryption by means of key agreement. However Diffie-Hellman is vulnerable to man-in-the-middle attacks. In other words, there is no guarantee that either side is sure of each others identity, making it possible for communication to be intercepted and altered without the receiving party knowing about it. It is thus recommended to use a private shared key to encrypt the key agreement handshaking, so that the identity of either party is confirmed.
This brings me back to my initial problem that resulted in me needing to use Diffie-Hellman, how can I use a private key in a silverlight client without hardcoding it either in the code or an xml file.
I'm all out of love on this one... is there any answer to this?
EDIT:
Remember that this is about a custom PHP web service that I rolled out on my own.
I found an RSA implementation i can use in Silverlight. It seems pretty safe to use this to encrypt the handshake for the DiffieHellman key agreement between the Silverlight client and PHP web service, and subsequently also use it to encrypt the symmetric key that was agreed upon (which is itself generated from the result of the key exchange by hashing it).
After this I'm pretty much guaranteed that all communication going to the web service has not been intercepted, modified and then retransmitted (MITM). However I believe it is still possible; technically, for an attacker to impersonate the silverlight client and send messages to the webservice (assuming they discover the url).
Security from unauthorized access is provided since the attacker does not know the "secret api" of my custom webservice, hence they are unable to communicate with it.
The only way to break this would be to brute force the webservice with whatever strings an attacker may suspect to be valid to try and get a response from the web service. I don't think you can brute force a variable length string. It sounds impractical.
Does anyone see a problem with this approach?
SSL/TLS suffers from the same problem that any Diffie-Hellman-based implementation you come up with would have, in that it can still be broken by a man-in-the-middle attack.
The reason TLS is secure and trusted is because the client, when receiving the server's certificate, authenticates it by checking that it is signed with another certificate from a known trusted identity - say, VeriSign. Thus far, this makes it impossible to enact a man-in-the-middle attack without having VeriSign's private key - when the interloper sends a fake certificate proclaiming to be the server, the client would easily detect that this certificate is not signed using the trusted identity's certificate, and bails out of the connection, displaying a warning to the user.
For your purposes, it's likely easiest to use TLS. To make it secure, you would generate a certificate for your server, and then embed in your client the public key for that certificate. The client can then verify that it is talking to your server, without having to expose the private key, which you don't have to distribute.
EDIT: In response to your comment on Jerry's answer, if your hosting provider doesn't allow SSL/TLS connections at all, preventing a man-in-the-middle attack will be tricky. If this is your only reason for avoiding TLS, I would suggest getting your provider to turn it on, or finding a provider that allows for it.
EDIT: In response to your edited question: even if you're now using RSA in your Silverlight client to send data to your web service, you cannot guarantee that the client itself has not been modified. It's quite possible for an attacker to dig into your client, determine the algorithm you're using to perform the encryption/handshake, and then write code to impersonate your client (or indeed, modify the client to include their code). Once they've done that, they can start analyzing your API and use it to make calls to your web service.
It's the same with SSL/TLS - the client can validate the identity of the host using the host's certificate, and as long as the host's server is secured, the client can trust the output from the host; however, there is no mechanism in which the host can 100% validate that the client is who they say they are, as the client will be run on a machine which does not have a controlled execution environment.
However - despite the above being true, and that it's possible that an attacker can compromise your system in this way, it's likely not probable -- unless you're working on a public-facing system that attracts a lot of attention/use, or a system that deals directly with money in some form, the attacker needs to make some effort before being able to send their own input to your web service.
Your best bet is to validate the input received by your web service thoroughly, and don't leave dangling APIs accessible that your regular client would never use.
The obvious solution would be to use WCF to establish an SSL or TLS connection instead of attempting to build that into the application.
I recommend starting with this JavaScript+PHP DH key Exchange protocol:
http://enanocms.org/News:Article/2008/02/20/Diffie_Hellman_key_exchange_implemented
You can then re-write the javascript in silverlight. I recommend using Wireshark to dump packets then you can use Meld or whatever to diff the packets to see where your implementation is differs from the original.
Good Luck!
(Disclaimer: I totally agree with the Enano dev team, this is not a full replacement of SSL and SSL should be used whenever possible.)
I have a database that many different client applications (a smattering of web services, some java apps and a few dot net applications) connect to. Not all of these are running on windows (Sadly, otherwise it would make this an easy answer question with just enabling windows authentication for database connections). At the moment, the passwords are stored in various configuration / properties files lying around the systems. Ideally, only the support staff have access to the servers where the files are running, but if someone else gains access to one of the servers, they would have enough database permissions to get a fair whack of data as it stands now.
My question then, What is the best way to keep the passwords configurable, without having it too easily available to the casual human reader?
Edit Just to clarify, DB server is Windows Server 2003, running MSSQL 2005.
PS: I don't see any questions that this duplicates, but if there are, please feel free to close this one.
I'm assuming you want to hide the passwords from casual observers. If they were evil, steely eyed observers with access to all the source code on one of the machines that connects, then they can get the password with a bit of reverse engineering.
Remember that you do not need to use the same protection for each different client. A few steps:-
Create different database accounts for different systems that access your database
Limit access on the database to only what they need using your inbuilt database GRANTs
Store a triple DES (or whatever) key inside a password manager class on your database. Use this to decrypt an encrypted value in your properties file.
We have also considered having the application prompt for a pass-phrase on startup but have not implemented this as it seems like a pain and your operations staff then need to know the password. It's probably less secure.
Let's assume the following common scenario:
You use the same code base for all environments and your code base has the database passwords for each environment.
The personnel (sysadmins, configuration managers) that have access to your production application server are allowed to know the production database passwords and no one else.
You don't want anyone with access to the source code to know what the production passwords are.
In a scenario like this, you can encrypt and store the production passwords in property files that your application. Within the application you can include a class that reads the passwords from the property file and decrypts it before passing it to the database driver. However, the key and the algorithm used to decrypt the password are not part of the source code but rather passed to the application as a system property at runtime. This decouples the knowledge of the key from the application source code and anyone with access to just the application source code will no longer be able to decrypt the password because they do not have access to the application's runtime environment (app server).
If you are using Java take a look at this for a more concrete example. The example uses Spring and Jasypt. I am confident that some thing like this can be extrapolated to other environments like .Net
At my old workplace we used to have a system whereby all passwords were encrypted (using Triple DES or whatever we were using at the time). The passwords were often stored in properties files (this was in a Java system).
When the password needed to be changed, we could simply use "!plaintext" as the value, and then our code would load it up, encrypt it, and store the encrypted value back in the properties file.
This meant that it was possible to change the password without knowing what the original value was - not sure if that's the kind of thing you were asking for!
It sounds like there is no easy answer (because of the different types of applications that connect)... really, the only issue I see is the Java Apps which seem to connect directly to your database. Is that correct?
If so, here's what you can do:
1) Change any client-side applications that connect directly to the DB to go through a service. (If they have to connect directly, then at least give them a first step to "get password" from a service, then they can connect directly).
2) Store the passwords in the web.config file (if you chose to do .Net web services), and then encrypt the "connection strings" section of the file.
Don't use passwords, server to server authentication can usually be performed by using a key file or a client cert or some other way other than a password.
You could use a reversible encryption algorithm e.g. Blowfish to store the passwords as a stopgap measure. There should be a number of free libraries you can use to build this into all your programs that need this access.
Bruce Schneier's page on Blowfish
Wikipedia article on Blowfish
For the java stuff, if you're using an app server see if you can define a data source, and your apps can get at the data source using JNDI. That way, managing the datasource (including connection details) is handled by the app server, and your application code has to do is ask for a datasource.
NTLM Authentication or LDAP-based (Active Directory) authentication should be available to you with a bit of effort. This would allow you to use your "windows authentication" across applications.
It may mean a bit of a migration for your operations staff, but SSO for a set of applications is nice.
Yes I have to agree with the option of storing the (salted) hashes. I would recommend a (salted) SHA256 hash of the password stored in the database. Also don't forget to enforce secure password rules.
My interpretation of your question is that you are asking specifically how to store configuration passwords that your code will use to connect to services it depends on such as a database or third party API. In that case, you may want to consider using a service which provides a secrets container such as Hashicorp's Vault.
You can think of vault as a web service your application can connect to in order to lookup the secrets your application needs at application runtime.
As an example, lets assume your application needs to connect to a database but you don't want to store your database credentials with your application source code in your version control system. Furthermore, lets assume that you want the database credentials used by your application to be different each time your application starts. In this case, you could enable and configure the database secret back end in vault. This means that vault will dynamically create your database credentials as a service, and then provide your application with a revocable leased token for some duration of time. Vault, of course, will allow you to store any secret in it.
Vault provides secure ways for your application to connect to it. One such authentication method uses what is known in vault as the Cubbyhole Secrets Engine.
Using encryption is not a good idea. If someone compromize the key he can decrypt it. Use a hash algorith with salt to store paswords. Hash algorithms are one way so its not reversible. But they are vulnerable to dictionary attacks so use salt (concatane plain text with something long and verbose than hash it). It also protect database from internal attacks.