I have an application that uses a digital certificate class 2 to download some files. I know this isn't a good idea but the application handles the input of the password automatically.
Now a new client wants this application but they do not want to give me the password because they're afraid I would be able to do anything with their certificate+password.
Is there any way I could either:
Use the certificate to download files WITHOUT the need to know the password.
or
Get a second certificate that would only let me download the files from a certain URL.
Any help regarding these topics will be greatly appreciated!
Use the certificate to download files WITHOUT the need to know the password.
Impossible. The password is used for encrypting the private keying material. Since you do not know the password, you don't know the private key, and you cannot use the certificate for authentication.
However, note that password have much less entropy than keys. If your client didn't thought a good password, it could be relatively easy to guess it by brute-force. This site claims that you can do about 30 million of password tries per day. Then, assuming a password with 28 bytes of entropy (i.e. 2^28 combinations), you can guess the password in one or two weeks.
Get a second certificate that would only let me download the files from a certain URL.
That part of the question depends on what certificates are accepted by the server...
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 am developing a console application. This application generates a self signed certificate and installs it in the current machine's certificate store.
The steps involved are :-
Generate a certificate
Create a pfx file
Install the pfx file
For these steps, I would need a password for protecting the private key and the pfx file.
However these passwords are used only during the execution of the exe.
Should I auto generate a password using some random number generation algorithm or accept the password as input from the user?
What are the security issues involved in both the scenarios?
Thanks for all the replies. Life time of the password is only till the pfx file gets generated. The program deletes the pfx file after installing it in the windows certificate store. In such a scenario I guess accepting password from user would not offer any security advantage over auto generating it.
I would like to add to this question further.
Once the password is available to the program how do u secure this password for its lifetime ? I am using .net and have read about secure strings in .net. But the secure string would have to be built from the string which doesn't solve the problem.
the code snippet looks like
string password = AutoGenerateOrGetPassword();
GenerateCertificateAndInstall(password);
How does one protect the password which is stored in memory during its lifetime ?
There shouldn't be any major security level difference or issues whether you auto generate or use a given password.
However, using an auto generated password will guarantee you a certain level of password complexity - this reduces to chances of brute force attack.
Using a given password would mean that someone (physically) knows the password. You won't know how complex the password user entered is going to be. Giving a password 'AAAA' will probably be less secure than a password that is given 'W0R!$%3D'.
Are you going to show the auto-generated password if it is done auto-generated manner?
I'd suggest that you go according to your software requirements. If this is not stated in the requirements, allow the user to choose between auto-generated or enter password.
I think a discussion "accepting passwords vs auto generating the password" is meanless in the context of your qestion if you make shure that the pfx-file is deleted after the import. It will only exist until beeing imported into "machine's certificate store."
If the pfx-file must be backed up or transferd via email/usbstick i prefer the "accepting passwords form user" variant because
Providing an inputform for the password plus implementing some logigic to make shure that the password ist strong enougn is easier than organizing that the user gets its pfx-file and the corresponding password via two independet channels. Sending pfx + password in one email is as secure as having no password at all.
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
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.
I'm working on a project in which remote clients need to log in to a webserver. I'm not looking for examples in any particular language; just a general idea of the security concerns involved.
The basic question is:
How should user credentials be passed to a webserver for verification?
I'm picturing your typical website login. One field for username, and another for password. You type in both and click "Log In". What happens next?
I can imagine a few scenarios:
Credentials are sent to the server as plain text. A server-side script creates a hash of the password and compares it to the stored hash for the user.
Credentials are encrypted locally, and the result is sent to the server. The server decrypts the credentials and continues as in #1
Something I haven't thought of yet? I'm new to this. Go easy on me!
Option #1 strikes me as weak because the credentials are sent over the internet in plain text.
I see option #2 as not much better than option #1. If someone intercepts the encrypted credentials, can they not just send those to the server another time, and still manage to log in?
Any insight is appreciated.
edit: the "Related" sidebar suggests this question, which mentions a client/server handshake with a salt added to the password. Is that the right way to go?
Option 1 is by far the default. The plaintext weakness is usually overcome by enforcing SSL during the login so that the password is at least encrypted during transit.
Edit: I suggest you follow the accepted answer for that question.
Don't forget to require a nonce for your request. This will help protect you against replay attacks.
Edit the second: Wayne thoughtfully mentioned that you should salt your password before you hash. Here are some basic tips:
It doesn't matter if your salt is a prefix, postfix, or infix
Your salt should be large, random, and complex.
Your salt should be unique per salted value. The salt itself doesn't need to be encrypted.
Why not SSL the communications? Being able to observe the conversation gives me insight into your app. Encrypt the entire communication, not just the credentials.
Edit: Always use salt for a locally stored hash. Windows continues to fail as far as brute forcing locally hashed passwords because they do not salt by default.
The simplest answer is to get an SSL certificate for your server. There's really no reason to mess around with creating your own encryption techniques in this particular application. As you've noted, if the connection isn't encrypted, you leave yourself open to man-in-the-middle attacks, regardless of whether the client or the server is doing the password encryption. Encrypt the connection, and you don't have to worry about it.
On the client side you only have a browser that can render HTML and submit forms. Who's gonna encrypt stuff?
Send login and password in plain text (SSL it if you have concerns). On the server side you can do whatever you want with it (preferrably hash and salt password before storing them in the database).
You might also want to consider using multiple iterations of the hash algorithm, 1000 iterations will slow things down nicely and make rainbow tables that much harder to create