I found the following claim in the documentation for Net::OpenSSH:
Note that using password
authentication in automated scripts is
a very bad idea. When possible, you
should use public key authentication
instead.
What's flawed in using password authentication in automated scripts?
Passwords are easier to guess/brute force than private keys (unless you are running Debian ;)
Imagine you have a user account which runs 120 different automated scripts. If you hardcode password into each of them you now have 120 places to change it.
If you place the password into a config file and have all 120 scripts read it from the file sooner or later somebody will accidentally make that file world readable. ssh won't work when the private key is not 600.
Somebody can decide to change user's password without thinking about the possibility of it being hardcoded in some script. You are more likely to stop and think before changing the private key.
Probably because with password authentication, you have to hard code the password itself into the script or at least into some sort of configuration file.
It's never a good idea to hard code your plain ssh password i think :)
Public key authentication should always be preferred for any remote resource. It is statistically impossible to guess the challenge response and can thwart MITM attacks. Although this does not rule out the possibility of the attacker being extremely lucky.
If the attacker can read files on the remote system, the password or the private key must be in plain text and there for can be read. Asymmetric cryptography isn't a magic wand that solves all problems.
One possibility for this warning in the docs is that if you use a password and the script isn't checking the sshd's public key then a MITM attack could obtain the clear text password. You should be checking the remote servers authentication by hard-coding the public key. The ssh command on the cli does this automatically and will throw a warning if a server's key changes. If you aren't checking the authentication credentials of the remote server and you are using public key authentication then an attacker can only MITM that session because the attacker will not be able to obtain the client's private key to re-auth.
Related
I configured msmtp with my gmail account.
I obviously want to avoid writing my password in plaintext format in the config file.
Luckily enough msmtp offer the option passwordeval which can be used to obtain the password from the output of an an executable.
The question is: how should I use it?
I found here the following suggestion:
passwordeval gpg -d /some/path/to/.msmtp.password.gpg
That doesn't make much sense to me: if someone is able to access my config file he will certainly manage to run such a command and obtain the password from gpg.
So I believe I'm left with the only option of obfuscating the password within the binary executable even if I read almost everywhere that this is bad!
My impossible-to-hack implementation is: if the sendmail process is running output the correct pass, otherwise give a fake pass.
Your suggestions?
Other (more secure) tricks different from storing the pass in the binary file?
From Sukima's comment:
The reason gpg -d works is because it requires the private key of the person the file is encrypted to. So just placing that encrypted file in the public it is still encrypted an only one person (the one with the secret key) can decrypt it. It is assumed that the secret key is locked up on the user's machine and not leaked. It also assumes that they have not setup any agents which cache the unlock password while a hacker has direct access to the same machine. All of which is highly unlikely in 99% of all attacks.
There is not a standard solution on how to save credentials with the constraint of
having to use the credentials in plain text later
and in an unattended way
on a system which is not completely controlled by you (if it is you just set appropriate rights on the files holding the secrets)
You have several solutions, none solves perfectly your problem:
encrypt your credentials in a symmetric way: you need to input the key to decrypt them
encrypt in an asymmetric way: you need to provide your private key, which must be stored somewhere (unattended approach) or keyed in
obfuscate: as you mention, this only protects from some population
get it from somewhere else - you need to identify a way or another your system
You need to take into account which risk is acceptable and go from there.
I'd like to encrypt the user data I store on my server so that it is safe if my server were to be compromised. Is the following a good way to do it:
Each user's password is the passphrase to a GPG keypair. All the user's data is encrypted using the public key before being saved to the database. The password is discarded and the keypair is kept only for the duration of the session, so the data can only be decrypted when the password is supplied.
From the point of view of someone compromising your server, the only way to ensure the data is safe is the way you are doing, when the user have to supply the key to decrypt every time.
Any other technique leaves some weakness that could be exploited.
But you have to be sure the other way (I mean when user provides the password) is secure too, using https and preventions against session attacks, cross scripting and etc.
If you do not have specific hardware to do an extra line of protection as when they are generated pseudo-random numbers based on time (as do the banks tokens) or something like that, the best idea is to keep the keys with the user or to use a third part storage with greater security as the SQL on Azure or Amazon.
I used the same approach after thought a lot about where to put my encrytion keys to make data obscure even if my server got compromised. The only secure way I found was "with the user".
your approach protects you from only 1 attack: stealing your database (and only if you encrypted keys properly). if your server gets compromised they can take your ssl private key and listen your network traffic (with users' keys)
Hi I am accessing a repository through a URL of type svn+ssh://
Reading the following quote from SVN and SSH from Adobe I am a little confused
"Before you configure Subversion or Dreamweaver for SVN+SSH, create an RSA key pair and configure the public key on the server. This public/private key pair is used to authenticate with the server, instead of storing and passing your password in plain text."
So if I just acces a repository by svn+ssh:// pe. from command line, my password is send in clear text ? I thought part of ssh was to encrypt the password, no ?
Maybe I was unclear, I have not generated any keypairs so use my password every time, does that change anything or is the quote written in confusing way ? Thank you.
Part of ssh is to encrypt everything, not just your password. So, your password would not be going over the wire in plain text.
SSH never sends passwords in plain text. However, non-SSH protocols such as svn:// may send the password in plain text. Adobe is recommending that users use SSH. Adobe also recommends that if SSH is used, then RSA key pairs are also used. Key pairs are easier because you don't have to keep typing your password for every operation (when used with an SSH agent).
There is no password at all in this case. All authentication happens based on key pair. One key is on your client machine, another one lies on the server. All traffic is also encrypted.
I am trying to find a technique to encrypt and decrypt a file in a program without hard coding the password into the program and without asking the user for it.
It would be nice if I could also decrypt the file from another program that I also am writing.
So far I haven't had much luck finding a good technique that looks secure enough for my liking.
I'm writing this in c# but the language isn't important I just need someone to point me in the right direction towards an algorithm/technique.
This is a recurring problem with no safe real solution. If you want to be able to encrypt/decrypt something safely, you need a key. Your program needs to know that key. If the key is stored, somebody else can find it and use it to access your encrypted data.
Think of it like this: If your program should be able to access the encrypted data without hard coding the key into the program and without asking the key from the user, then why can't any other program do the same and acquire the encrypted data?
I think you need to define the problem further before you are ready to talk about how to code it.
Specifically, who should be able to decrypt the data? And what technique would you use to prevent others from doing it.
As it stands, the question may was well be "I'd like a lock on my door that doesn't require a key." The statement hasn't really defined the goal with enough clarity.
Put a web resource up with the password on it, and have the code request that web resource. Of course, to do this securely involves SSL and a webhost, but it fits your needs.
If your program features user accounts with their own passwords, you could do something like:
Set up a users table containing a column for storing an encrypted copy of the program-wide password.
Encrypt a copy of the program-wide password in each user's account using the user's password as the key.
When the user logs in, the system password is decrypted using their password and stored as a session-length cookie (SSL only) on their browser.
In this way, each user can get a copy of the system password silently in the background.
HOWEVER, this approach has some serious drawbacks.
First, the system password becomes no more secure than the WEAKEST user password. If Bob from Accounting sets his password to "password123", then that can be used to retrieve a copy of the system password.
Second, an attentive attacker will notice that cookie contains the system password, and then you're screwed.
You could obviate that by actually storing the decrypted password on a third machine accessed via SSL, then retrieve it for each transaction based on the user's session ID; but this would mean if the third server goes down for any reason, your entire system is down. It would also impose performance penalties, and your data server's security would depend on the password server's security.
And after all that convolution, in the end there's no really good solution; you just have to either prompt them for the password or store it on the server itself and lock the server down as tight as you can.
In cryptography the strength of the encryption scheme is the function of secrecy and strength of the key. This means that the key must be secret (i.e. not accessible to the attacker). Now, if there key is not in user's hand and not in the application code, where it is? And how secret it is?
So you need to re-think your task. Maybe good obfuscation of the key will drive away most not-very-skilled attackers. The simplest way to obfuscate the key is to use some text phrase of your program as a key. This makes operations with the key less obvious for an occasional lurker (professionals know different ways to find the encryption keys in the application).
Maybe the best answer could be a password generated by some means (like the size of a file or any other fixed value in the system). So you store in code the way to obtain the password rather than the password itself.
Situation 1 - Connecting the server to the database:
Its always said that passwords should not be stored in plain text, however to connect to the mysql database requires the password, in plain text it seems... I'm guessing the best solution to this is to store it in an encrypted form, decrypt it in my app as needed and then erase it from memory (SecureZeroMemory in windows I guess so the compiler cant optimise it out).
Situation 2 - Users logging into the server from a remote computer:
As for users passwords my plan is to never actually store the original password at all.
Instead I will store a randomly generated "salt", for each user, prefix there password with it then hash it, which seems to be a relatively common way. However I don't have an SSL connection available at this point, so I'm guessing the plain text passwords could be intercepted, what's a good solution to this?
What are good algorithms (links to C/C++ implementations would be handy as well if you have them) for doing this, a look on the net comes up with 100's of them?
EDIT:
If I got SSL, would the following be secure (assuming a strong hash algorithm is used), or should a different method be used?
Client requests salt for a user name
Client prefixes password with salt, then hashes it before sending the hash to the server
Server compares hash recieved to the one on the server for that user name
Connecting the server to the database
Just storing the database password in the server - encrypted or not - is a bad idea. It is obvious storing it in plain text, of course. And if you just store it encrypted, the server still needs the key to decode it. It is usually not very hard to find the key in the server code. The best solution is to let the user starting the server enter the password and store it nowhere. Alternatively - and probably even better - you can store all sensitive information - for example database users, passwords, and so on - encrypted and let the user starting the server enter a master key to decrypt this information.
Connecting a user to the server
This is really a hard problem and easy to mess up. A quote from this great article article on the topic I absolutely recommend reading.
No, really. Use someone else’s password system. Don’t build your own.
A good solution might be using the Secure Remote Password Protocol.
You are correct that if you're not using SSL then the passwords can be intercepted.
It is common practice to never decrypt a user's password, so keep it stored hashed with a salt and when the user types in their password you will add the salt and hash it, comparing it with the stored, hashed password. This will allow you to never have the decrypted version of the password every.
You really should look into securing the connection so that the password is secure when the user types it in.
Update to answer edited question:
If you have the communication secured using SSL you can still use any number of extra measures of security you like including hashing the password. As added security it is a good idea to remember that the password you store should be stored hashed with a salt. That salt should be kept safe and never be accessible anywhere except by your application. This way when the user submits the password you just add the salt and hash and you compare that version with the stored version.
Situation 1 - Connecting the server to the database
There isn't an easy answer here. In order to connect, the server needs the password (or symmetric key, or private key or whatever). It must get it either from the disk or some external means (like an administrator typing it at startup). Adding some indirection, such as encrypting all the sensitive stuff under a master password, can add some convenience but otherwise doesn't change the situation.
Typically, it is fine to put the password or key in a file on a server. If you do this, make sure to set the permissions on the file so that only the users that need it have access to it. This is an excellent reason to have different processes on your system run as different users, and to set up separate roles/accounts and passwords for each.
Situation 2 - Users logging into the server from a remote computer
You are headed in the right direction here, I think. What it sounds like you're asking for is a secure authentication protocol. You want one that provides mutual authentication and prevents a man-in-the-middle attack by failing if such an attack is attempted. There are many to choose from of course.
It is also worth mulling whether your authentication should operate based on "something you know" (passwords) or "something you have" (public/private keys). Assuming based on your question that what we're looking for is passwords, two that I like are SRP and Kerberos.
SRP was mentioned earlier, and that doesn't get nearly the attention it deserves. SRP has the advantage that it doesn't require the server to know the password, or key, or anything that an attacker could use to gain access. If you broke into a correctly configured server using SRP and stole all the data, you'd still need to do something like a dictionary attack on each key individually before you had anything you could use to impersonate a user.
I also like Kerberos because it is supported by tons of software (I know Postgres supports it, I've only found mentions of mysql not supporting any good authentication technology) and has a system of 'tickets' that provides a single sign on capability. Kerberos needs some other technology to help strengthen its initial authentication exchange and SRP would be great for that but I'm not sure they've done that yet. Something about it making the KDC (key server) stateful I think.
Kerberos' weakness is that you have to be more wary of the server storing the keys. While it doesn't store the passwords in plaintext, it does store the keys, which are essentially hashed versions of the passwords. And while the client doesn't exactly send either the password or the key straight over when authenticating (this is a Real auth protocol after all), it does use the hashed password as the key, and so anyone else who knows the algorithm and knows the key could do the same. We say that the server stores a "password equivalent". As a result, all the manuals tell administrators to put the kerberos services on their own separate, locked-down boxes to minimize the chance of compromising their contents.
The nice thing is, once you settle on a strong authentication exchange, other good things typically fall out of it for free. You end up with both parties sharing a mutual 'secret' that can be used once for the duration of the session, never sent over the wire, and can't be known by a third party. Want encryption? There's the key, all ready to go. This is exactly how SRP-secured SSL is defined in RFC 5054.
Not sure if this is what you are asking for.
But a simple PHP example using the built in sha1 function:
// Check the hashed password from the database
if (sha1($salt.$password) == $providedPassword)
{
// User is authenticated
return TRUE;
}
else
{
// User is not authenticated
return FALSE;
}
One thing you could do is also hash the password with javascript before it is sent over the wire. The question is how is the salt string shared between client and server? One possibility is to use a session variable. And then use the session variable to unhash the password afterwards on the server. This would mean that the man in the middle would need to know one other piece of info to make sense of the password. Not as secure as SSL, but perhaps an extra layer of defense against casual network sniffers.
I could also imagine a hashing scheme linked to some sort of captcha system used to salt the password on the local client before sending over the wire. The client would be providing the text for the salt string by completing the captcha. You could look it up on your end.
The main concern is the man in the middle not understanding the plain text password.
SSL should be used, but the above techniques might be useful where SSL is not possible.
Newer MySQL uses hashed password over the wire, so you don't have to worry about man-in-the-middle.
If you worry about the password stored in your configuration file, you can encrypt the configuration file with a password. However, the problem is that you have to enter a password to start your application.
I wrote a similar application over 15 years ago. Back then, PGP was my choice. I am not even sure it's still around.