views:

845

answers:

15

My application connects to an FTP server with a username and password. I can create an encryption routine to encrypt and decrypt the password, but anybody with access to the source code and the encrypted password can decrypt the password.

Is there an easy way to prevent every human being from knowing the entire password used by an application? (I think it's okay if multiple people know part of the password.)

EDIT: I know FTP is not secure. Ideally, I'd like a technique that would work in any situation where a username and password are required (e.g. a database connection).

+2  A: 

You can refer my old question and the answers here. How to store passwords in Winforms application?. But, looking forward to some other ideas too.

Gulzar
A: 

In essence, no. You can make it difficult, but any scheme which has code running on someone else's computer is suspectible to attack. How does the FTP server know that it is talking to your application, and not someone who has hacked what they need out of your application.

Rob Walker
A: 

No, there is no way to do this securely. ftp isn't a secure protocol anyway so people wouldn't need the source code to see your username and password, just a local network sniffer. You could avoid that problem by using ssh tunneling, but if you ship the source code it will always be trivial for people with access to it to get the username and password out of it. Even without source and even with a secure protocol, a dedicated attacker with a disassembler/debugger and some spare time will still be able to get this info out of the executable. If a username and password must be secure, don't include it in the code, even if obfuscated!

+1  A: 

I tried many methods, and I don't think encryption is the way in this case. Instead, store the password in a configuration file, such as web.config/app.config/etc or the Windows registry, or a file in /etc or any other place which developers don't have access to (on the production environment), but you do.

Moshe
A: 

the actual answer is no. The standard FTP client server communication actually passes the username and password across the network in a unencrypted form. So even if you try and use some scheme to encrypted the actual data inside your application, anyone with a copy of Ethereal will be able to sniff it out.

stephenbayer
+12  A: 

No. All an app user has to do is sniff their own network traffic (easy to do with Wireshark or such).

You really need a way to give each user a unique token of some sort.

Edit - more info:

Any system that relies on "secret" login information that is the same for every copy of the application is flawed by design. In order to keep things secure, every install of your app must have a unique secret that it uses to authenticate with the server. How you accomplish that is dependent on how you license/distribute your app. Here is how I would do it. (Perform all communication over an SSL connection).

  1. App is launched for the first time - it sees that it has no authentication information saved.
  2. App prompts you for a registration code, email address and/or however you want to identify your users.
  3. App generates a public/private keypair and submits the public key with your ID info from step 2 to the server.
  4. Server remembers your key and uses it to identify your app from now on.

Alternate step 3 is: app submits info from step 2 and server sends back a hash signature of the info + salt. Hash signature is now your app's key.

The important thing is that there is no "secret" shared between all your users.

Neall
+2  A: 

Shouldn't there be at least one person who has access to a password or the key? Our devs don't have access to production servers. That allows the systems guys, who are allowed to know the passwords, to set the passwords when they deploy the software.

Code the software to be configurable and then keep your devs out.

mspmsp
The password needs to be accessible somehow, but that doesn't necessarily mean that one person needs to know the entire password. For example, there are systems that let one user know the first half of the password, and another user can know the second half.
Jim
As a more general matter, you don't need to know the password to set it, you only need to know what it will be. In some cases it makes sense to get someone with some sort of "admin" access (whatever that means in a given system) write-only access to a password.
Jon Hanna
+2  A: 

No, there is no easy way: you can obfuscate things as much as you want, but if the plaintext password is available to the application at any point, without requiring access to any resources other than its own source code, it can be extracted by any human with access to that same source code as well.

When using a protocol like FTP, the whole exercise is a bit pointless anyway: anyone capable of downloading Wireshark can sniff the credentials off the network wire in seconds, if not less.

Steps towards properly solving your issue:

  • Switch to a secure protocol, such as SFTP or FTP+SSL
  • Use public-key authentication instead of a password (both SFTP and FTP+SSL support this, albeit in slightly different ways)
  • Provide each deployment of the software with a (preferably unique, so you can detect credential sharing and disable the compromised accounts) copy of the private key/certificate required to log in
  • Store the private key/certificate in the most secure way possible on the platform you're running on. On Windows, this means using the Certificate Store -- see this MSDN Magazine article for a nice introduction

EDIT (after modification of original question): the first paragraph of my reply applies equally to things like database passwords, etc. The solution for those situations gets even more platform-specific. If your particular database/whatever/OS combination does not support secure logons, there's not all that much you can do.

For example: on Windows, SQL Server supports NTLM authentication, allowing you to set database access rights based on existing Windows accounts, giving you automatic secure storage and transmission of passwords which is relatively hard to bypass. If NTLM authentication can't be used, the best you can do (as is the recommended practice on the .NET Framework) is to store the password, encrypted with a machine-specific key, in a configuration file. However, that 'protection' is trivially bypassed using a debugger, since the plaintext password is required at some point.

mdb
A: 

Whatever kind of encryption you use, the password needs to be encrypted before your app can connect to the ftp. Any user can run your app in a debugger, trace until that point and then pick the password from memory. In that way, complete security for your scenario is impossible.

That being said, you can put the encrypted password in a config file that is read during runtime. Let the developers connect to a different ftp (or with a different account that later is removed), and put the encrypted password you want to protect in the config file when you deploy the app.

Treb
A: 

One way to do this is to host the application on a server. If the password is stored in a restricted area of the server, then those using the application will not have access to it. In fact, they will have no access to the application except through the interface provided. This is one reason why web-apps are getting so popular.

In this particular case, where the source code is still available to them, you just have to make sure the password is not stored with the source code, but only on the secure server, and accessable only by the account that is hosting the application on the server.

Jeffrey L Whitledge
A: 

just to throw ideas around:

  1. store the password in the binary, in a place you allocated for it.
  2. password can change based on time (day) or something, but if they run your code they can get it too.
  3. maybe do something with public key/ private key.(signature in encryption can identify the user. this info can be retrieved at runtime, I think from his/her key. it's like a challenge, but you'd need to build/program another server just for this authentication part. perhaps there are more known industrially accepted ways..

ftp by the way isn't secure. u'll need sftp or ftps to avoid transmitting clear text.

A: 

I guess you've see enough "no" answers already. I'd like to point out (without answering directly to your question) that a similar problem has been (almost) solved with jdbc-datasources in Web-/Application servers: These are resources, basically connection factories, that provide already-connected database connections without the application needing to worry about any connection setup, including names and passwords. The connection is established by the appserver, the appserver also reads the configuration file and knows the password.

I don't know the vocabulary for this in other environments (or applicability), but as you asked language-agnostic and I'm not directly answering to your questions, I figure it's ok to limit the example to Java.

If you find/write a similar abstraction that provides the ftp-connection you might keep programmers with sourcecode from knowing the passwords (because only connection objects that are provided by some "container" are used). It will not help against wiretapping or people with debugging access to the running application though.

Hope this helps, even if it doesn't answer directly and is no strict "yes" ;-)

Olaf
A: 

Maybe this answer will help depending on your environment. Ultimately though, because people are involved in the process the answer is "not bloody likely".

  • Save the username/password combination in a configuration file.
  • Setup a staging server with one username/password, the testing server with another, and the product server with yet another username/password.
  • The password in the config file (which the programmers will all know) is for the staging server. The username/password given to the test group is for the test server.
  • Make sure the production/test server has a different username/password.
  • Distribute the config file with the correct production username/password with the product.
ceretullis
A: 

Not sure about what you need... if you looking for a way to hardcode a private password, dismiss my comment.

But if you are looking for a way to store password...

I think, what you are looking for is to save a hash of the password instead of the password itself. That way, even if a programmer have your password check algorithm and the password hash from the database, he will not be able to decrypt the password.

Hapkido
A: 

What he's up to is a major cause of paranoia, useless paranoia. If you don't trust the people in your employ to keep your data secure, get other people.

The problem here is not one you can solve using software, it's a human resource problem. Two people, each having part of the password, will surely in time find one another for example, in which case two people now will know the entire password.

And as you yourself point out even if you were to make it so no single person has the password (except of course the person actually setting the password to the server in the first place...) it is still easy to intercept over the wire.

It's the same old problem of "I want noone to get access to the computer" which can only be done by unplugging the computer from everything, welding it into a steel box, pouring concrete over that, and shooting the thing into deep space.

jwenting