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.
Related
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.
I was wondering, whether there is a known safe way to store username and password safely for desktop application.
For example, the open source KeyPass
Let's say I get access to user local computer, grab all its KeyPass's configuration files, and step through KeyPass source code, is that I can reverse the user username and password after then?
No.
There is the concept of a one-way function. That is, if we have the relationship
y = f(x)
And we know y and f, it might still take a lot of time and effort to find x.
Example one-way functions (as far as we know they are, at least...) are the SHA algorithms.
KeePass keeps all the data symmetrically encrypted in a local store via AES so unless you get hold of the master password, your chances of decryption are pretty minuscule. The master password itself is stored as a SHA-256 hash (I assume salted) which means that so long as it has good entropy to begin with, your chances of getting hold of it are about the same as breaking the encryption.
So yes, this is a very safe way of storing credentials. Not foolproof, but about as good as you practically get.
You can store a password safely by using, say, a well known strong encryption algorithm, like AES.
HOWEVER, you cannot make the procedure that depends on the password 100% secure. Since the actual functionality of a desktop app is right inside the app's code, there will always be a way for the attacker to access that without even needing to know your password. Even using polymorphic self modifying code based on the encrypted key is still crackable (that is actually a protection that CuteFTP was using in the past, but still just xoring user's ftp passwords to store them 'safely').
Bearing that in mind, encryption does make it more difficult and at least, even if people crack the app, they may not be able to recover your original password.
I've found numerous posts on stackoverflow on how to store user passwords. However, I need to know what is the best way to store a password that my application needs to communicate with another application via the web? Currently, our web app needs to transmit data to a remote website. To upload the data, our web app reads the password from a text file and creates the header with payloads and submits via https.
This password in plain text on the file system is the issue. Is there any way to store the password more securely?
This is a linux os and the application is written in python and is not compiled.
Further clarification:
There are no users involved in this process at all. The password stored in the file system is used by the other web app to authenticate the web app that is making the request. To put it in the words of a commenter below:
"In this case, the application is the client to another remote application."
From the question it seems you need to store password in such a way, that it can be read and used in an automated transaction with another site. You could encrypt the password and store it encrypted in the file, then decrypt it using a key stored elsewhere in your system before using it. This makes difficulties to someone that gets access to the file from using the password, as they now have to find the key and encryption algorithm used, so they can decrypt it.
As defense, more lesser defense is always better than one strong defense that fails when breached. Moreover, I would also secure the file containing the password, rather than the password itself. Configure your webserver to disable possibility to serve the file containing the password, and try to set the process needing the file to run under a separate account, so you can restrict the access to the file to account running the process and admin accounts only.
I don't think you will find a foolproof way to do this. I would suggest a combination of things to achieve 'security by obscurity':
store the password file on a different computer than the one which will use it
store the file path in a separate config file on the app nachine
use permissions to limit access to the config and password files to your process only
audit file access if your system allows it (keep a log of who touched the files)
give the folders and files innocuous names (/usr/joe/kittens.txt?)
block physical access to the computer(s) (offsite hosting, or locked closet, or something)
You can use a two-way key encryption algorithms like RSA,
The password is stored encrypted (by a key, which is stored in the user's brain) on the filesystem, but to decode the password, the user must enter the key.
At the very least you should use permissions (if you are on a filesystem which supports them) to ensure that you are the only one able to read the file.
In addition, if your app is compiled, it would not be too difficult to encrypt the password with a hard-coded passphrase. If the code is not compiled this method wouldn't really be helpful, as a would-be attacker could just read the source and determine the encryption.
You can store it as a result of hash algorithm, this is one way algorithm (eg. MD5 or SHA). On authentication you calc MD5 of password typed by user and checking equality with your stored MD5 password hash for this user. If is equal password is ok.
For more information about hasing algorithms you can visit:
http://en.wikipedia.org/wiki/Secure_Hash_Algorithm
http://en.wikipedia.org/wiki/MD5
Is your web application hosted on a farm? If not then a technology such as DPAPI will allow you to encrypt the password so that it can only be decrypted on the machine it was encrypted on.
From memory there can be problems with using it on a web farm though, as you need to go and re-encrypt the value for each server.
If it is a web farm then you probably want to use some form of RSA encryption as has been suggested in other answers.
EDIT: DPAPI is only good if you are hosting on windows of course...
Protecting the Automatic Logon Password
The LsaStorePrivateData function can be used by server applications to store client and machine passwords.
Windows only
I don't think you are understanding the answers provided. You don't ever store a plain-text password anywhere, nor do you transmit it to another device.
You wrote: Sorry, but the issue is storing a
password on the file system... This
password is needed to authenticate by
the other web app.
You can't count on file system protections to keep plain-text safe which is why others have responded that you need SHA or similar. If you think that a hashed password can't be sufficient for authentication, you don't understand the relevant algorithm:
get password P from user
store encrypted (e.g. salted hash)
password Q someplace relatively
secure
forget P (even clear the buffer you
used to read it)
send Q to remote host H
H gets password P' from user when
needed
H computes Q' from P', compares Q'
to Q for equality
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.
I have a database that contains sensitive information. I can encrypt / decrypt the data on the read write operations. The problem is that I need to store the key in the application. If someone has hacked their way in such they have access to the database then they can also grab the application (java) decomplie it and pull the key.
This seems like a speed bump at best. What other solutions are available?
The only thing you can do is make it difficult to extract the key from your application. You can't make it impossible. If you give someone a box with contents that you're trying to protect, you have to give them the key if you want them to be able to access the contents. Once you give them the key they can do whatever they want… if they take the trouble of finding the key.
This is a case of Bob and Eve being the same person, you want to give Bob access but stop Eve from seeing it.
This is DRM, it doesn't work.
I am assuming you have some way to verify the credentials of the user before allowing them to access the database?
Usually the architecture for these kinds of things is as follows:
Database
Server
Client
The Client connects to the Server, which then connects to the Database.
The Server makes sure the Client authenticates correctly before allowing them access to sensitive information. The decryption key is stored only on the server. Noone should have access to the server, and especially the file that contains the key. This way the clients do not have any encryption/decryption they have to do, and do not have to store any keys.
Read up on keystores.
Require the user to enter a passphrase to access their data. Burying the key in the code is security by obscurity.
Store the keys in a CSP container. Consider the Java CSP here .
This is IMO the safest way possible. But you can also consider storing the key in a file which is protected by the operating system using some kind of ACL.
require the user to log in using a strong password; use the password as the key for a symmetric encryption algorithm to decrypt the asymmetric database key
keep the db key in secure memory while the application is running (if that is an option)
Encrypt the key (using DPAPI), put it in a file, put an ACL on that file etc...