I'm using a stored procedure to check the username and password on login attempts. - The passwords are stored using the password() function in MySQL.
And the login works fine, using the stored procedure, the problem is that I have a function that enables the user to change the password, how should I update it? as MD5 through PHP? or should I build a new stored procedure?
Thanks :)
You're not supposed to use the PASSWORD() function for your application-level passwords.
http://dev.mysql.com/doc/refman/5.6/en/encryption-functions.html#function_password says:
Note
The PASSWORD() function is used by the authentication system in
MySQL Server; you should not use it in your own applications. For that
purpose, consider MD5() or SHA2() instead. Also see RFC 2195, section
2 (Challenge-Response Authentication Mechanism (CRAM)), for more
information about handling passwords and authentication securely in
your applications.
If you use a standard cryptographic hash method like SHA2, you can perform the hashing in PHP, using the hash extension. Hashes calculated with the same algorithm in PHP are compatible with those calculated in MySQL.
This seems like a really easy one but I really can't figure it out. I want to use Auth::attempt($credentials) in Laravel 4 but with a password that has already been hashed (since it's an API). It works when I send the unhashed password, but I don't understand how to tell Auth to “not hash” the given password.
Quick “demo”
What works:
Auth::attempt([Request::getUser(), Request::getPassword()]);
curl --user username:notHashedPassword localhost:8000/api/
What doesn't work:
Auth::attempt([Request::getUser(), Request::getPassword()]);
curl --user username:$2y$08$xo7HpxFyeF2UKHOYs/e localhost:8000/api/
Are there any arguments I could pass to Auth::attempt() that would tell it to use it as it is instead of trying to rehash it (as I think it does)?
You can login the user manually
$user = User::find($id);
if ($user->password == Request::getPassword()) {
Auth::login($user->id);
}
You really shouldn't be hashing the password before you are sending them. How are you going to be able to hash the password properly prior to sending it without the salt? If you have access to the salt before sending the password then why are you using an API?
If you are worried about security of passing an un-hashed password, then you should be using SSL to ensure a secure transfer of data.
Don't consider an API any different then using a web page -- and you don't salt passwords before you submit a form on a website, instead if you need that level of security you rely on https / SSL.
The hashing method used by Laravel generates a different hash each time (even for the same string). You can read more about this in Hashing for Laravel. As you can read, it doesn't hash both strings and compare them, instead it uses the unhashed string to compare with the hash.
If you really do want to do this you'll need to implement your own Auth Provider and a different hashing algorithm that allows you to compare hashes.
If you're concerned about security you should consider HTTPS so that secure details (including passwords) are never sent in plain text.
We have a PHP application that stores passwords just using the MD5 function (with no salt).
We have OpenSSH set to use pam-mysql to authenticate users from the same database.
We would like to switch to use hashed passwords and we are considering either: 1. doing it ourselves, (something like md5($salt."$".$password) or hash("sha256", $salt."$".$password)), or 2. using php's crypt function (which uses the OS crypt(3) if available).
The problem is that I have not found whether pam-mysql supports crypt(3) or any replacement pam module that does.
crpyt(3) uses a user supplied algorithm and salt: crypt('password', '$5$saltstring$') for sha256 which returns $5$saltstring$OH4IDuTlsuTYPdED1gsuiRMyTAwNlRWyA6Xr3I4/dQ5. Any language that uses the crypt(3) library will see that string and know to use sha256 with the given hash and expect the given result.
Is the first method sufficient or is there some PAM module out there that supports MySQL and crypt(3)?
Use sha512, either a mysql implementation or a php implementation. If you use md5 you're using a known insecure function which opens you up to liability.
you may also use 3DES encryption for stronger security.
I am looking for a way to insert encrypted passwords into a database (MySQL) that I can decrypt later. I've done research and I've came to the conclusion that bcrypt would be the more secure way to store passwords, but then I can't get them back, and it's important that I know their passwords in case I need to login to their system (I don't want to rely on IP authentication).
http://php.net/manual/es/function.mcrypt-cbc.php has some good examples of using a library for encryption on both PHP and PERL, but PERL requires an additional library and PHP needs to be a certain version.
I am looking for a solution that has ability to run on PERL and PHP natively (no additional libraries) with versions that atleast a year old. No PHP 5.3 functions or anything of the like.
The system only has 100 or so users, so there isn't a huge risk of someone even getting access to the database, but just incase I want some kind of protection. If need be, I would be OK with having to add a library to PERL, but I can't really be picky with a PHP library or require PHP version higher than 5.0
If you're using MySQL you may want to look into using mysql functions such AES_ENCRYPT/AES_DECRYPT:
http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html
Using a standard hashing function (e.g. one of the sha versions) does mean that you can't get the password back but it doesn't mean you can't log in to their system.
Just update the password hash in the database with a known one (e.g. update user set password = sha1('password') etc), log in, then update the password back to the old hash. You're in, and their password is back to how it was.
If you're encrypting and decrypting, then the keys will need to be on the server; if you're compromised, the attacker will have access to the keys as well, so you might as well leave the passwords unencrypted if you're not going to hash them.
Just hash the passwords using SHA256 or SHA512. It should be enough. Now, you said you want to know their passwords so you can login into their account. You, as the administrator, should have the ability to login as the user without knowing their passwords.
If you need to login as the user then I am guessing you need to change something? Well, an administrator should be able to change users data without having to be logged in as them...
So I can only say fix your system.
I have a PHP app that needs to run bash scripts, and provide a username & password (for remote systems).
I need to store these credentials somewhere that is accessible by my PHP (web) app.
The logical place is the database (currently MySQL, but will be agnostic).
The problem with the "standard" way of hashing and storing the credentials, is that it is not reversible. I have to be able to get the credentials out as unencrypted clear text, to be able to insert the data into bash scripts.
Does anyone have any suggestions for a secure way to go about this ?
I thought maybe PKI'ing the credentials, and storing the result in the DB. Then use the private key to unencrypt (PHP can do that). Store the scripts to do this outside the web root.
Any thoughts much appreciated.
First, to state the (hopefully) obvious, if you can in any way at all avoid storing usernames and passwords do so; it's a big responsibility and if your credential store is breached it may provide access to many other places for the same users (due to password sharing).
Second, if you must store credentials prefer rather to stored passwords using a non-reversible, salted cryptographic hash, so if you data is compromised the passwords cannot easily be reverse-engineered and there's no need to store a decryption key at all.
If you must store decryptable credentials:
Choose a good encryption algorithm - AES-256, 3DES (dated), or a public key cipher (though I think that's unnecessary for this use). Use cryptographic software from a reputable trustworthy source - DO NOT ATTEMPT TO ROLL YOUR OWN, YOU WILL LIKELY GET IT WRONG.
Use a secure random generator to generate your keys. Weak randomness is the number one cause of encryption related security failures, not cipher algorithms.
Store the encryption/decryption key(s) separately from your database, in an O/S secured file, accessible only to your applications runtime profile. That way, if your DB is breached (e.g. through SQL injection) your key is not automatically vulnerable, since that would require access to to the HDD in general. If your O/S supports file encryption tied to a profile, use it - it can only help and it's generally transparent (e.g. NTFS encryption).
If practical, store the keys themselves encrypted with a primary password. This usually means your app. will need that password keyed in at startup - it does no good to supply it in a parameter from a script since if your HDD is breached you must assume that both the key file and the script can be viewed.
For each credential set, store a salt (unencrypted) along with the encrypted data; this is used to "prime" the encryption cipher such that two identical passwords do not produce the same cipher text - since that gives away that the passwords are the same.
If the username is not necessary to locate the account record (which in your case it is not), encrypt both the username and password. If you encrypt both, encrypt them as one encryption run, e.g
userAndPass=(user+":"+pass);
encryptInit();
encrypt(salt);
encrypt(userAndPass);
cipherText=encryptFinal();
and store the singular blob, so that there is less occurrence of short cipher texts, which are easier to break, and the username further salts the password.
PS: I don't program in PHP so cannot comment on suitable crypto s/w in that environment.
You'll need to look into good 2 way cryptographic methods, and my general rule of thumb is:
If you implement your own cryptographic code you will fail.
So, find a good implementation that is well verified, and utilize that.
There is probably some good info here:
http://phpsec.org/library/
Check this library: PECL gnupg it provides you methods to interact with gnupg. You can easily encrypt and decrypt data, using safe public-key cryptographic algorithms.
I would suggest you not store the passwords, but use passwordless ssh connection from the host to the remote system by generating a ssh key and storing your public key in the remote system's authorized_keys file. Then you would only need to establish connectivity during configuration. Admittedly not quite answering your question, but storing passwords in a reversible form is a slippery slope to a security breach imho, although I am sure smarter brains than mine can make it safe.
One easy way to get started is to use mysql's ENCODE() and DECODE() functions. I don't know what algorithm is used underneath, but it's easy enough to use:
INSERT INTO tbl_passwords SET encoded_pw = ENCODE('r00t', 'my-salt-string');
and
SELECT DECODE(encoded_pw, 'my-salt-string') FROM tbl_passwords;
If you go the PKI, and I would, make sure you safe guard your private keys! The strong encryption provided by PKI is only as secure as your keys.
I think you're on target. Look at GPG for a good, open encryption library
It looks like you pretty much have two methods of doing this:
1) Like you suggested use an encryption algorithm or algorithms which can then be decrypted and used for authentication in your scripts. You can use the MCrypt library in PHP to accomplish this.
2) Depending on the required level of security and your script's level of vulnerability, you could use a secure hash, key, or some other hard to guess unique identifier that you can use to hijack each user's account within the confines of the script.
As many stated you scenario requires that you encrypt username and password. I would recommend that you check out the mcrypt extension of php for encryption/decryption.
I think I am going to investigate compiling a PHP script with the credentials embedded, on the fly, from the web app.
I would ask for the credentials (for a given use), then create and compile a new PHP script, for this use only. That way, the script will only do what I need, and should not be "readable". I think this sounds like the safest way to do this.
Will try using Roadsend. http://www.roadsend.com/
Just to follow up on the suggestion to use MySQL encode and decode functions, the manual is vague on just how these work:
The strength of the encryption is based on how good the random generator is. It should suffice for short strings.
But what I'd suggest is that you can instead use the built-in MySQL 5.0 AES functions; AES_ENCRYPT() and AES_DECRYPT()
SELECT AES_ENCRYPT('secret squirrel', '12345678') AS encoded
=> ØA;J×ÍfOU»] É8
SELECT AES_DECRYPT('ØA;J×ÍfOU»] É8', '12345678') AS decoded
=> secret squirrel
These use 128-bit AES which should be strong enough for most purposes. As others commented, using a salt value and a key with a high entropy is a good practice.
For PHP, it is important to note that AES encryption is implemented via MCRYPT_RIJNDAEL functions. Don't go paying for a non-open implementation when PHP has them available.
See the PHP page discussing available ciphers for more information.