Welcome Guest, Not a member yet? Register   Sign In
Best way to handle passwords using CI library?
#11

[eluser]Elliot Haughin[/eluser]
Quote:so I switched BambooInvoice to using SHA1, but then after a little while I realised they were actually just as secure. Yes the encode()’s strings can be decoded, but not if they are using an encryption key.

The fact of the matter is, if one method can be converted back to plain text 'some how' (with the encryption key), and the other method can't be converted back to plain text, then it is by very nature more secure.

The reason I used the _prep_password function is because you could mix it up a bit and build your own 'special' crazy salting method to make it extremely secure:

Code:
return sha1($password.$this->config->item('encryption_key');

// OR
return sha1($this->config->item('encryption_key').$password);

// OR
// Build a salty beast like

$password = 'password_magic';

$password_chars = str_split($password);
$key_chars = str_split($this->config->item('encryption_key'));


foreach($key_chars as $key => $char):

     $salted_up .= $char;
     $salted_up .= (!empty($password_chars[$key])) ? $password_chars[$key] : '';

endforeach;

// output would be: NpeaOs5sCw8o8ridv_7muaog0i9cU2E20iJF0iUiz8R9zm

The more 'bespoke' you can make your hashing algorithm, the better.
The above, which merges the characters, assumes that the encryption_key is always longer than the password.
#12

[eluser]Negligence[/eluser]
[quote author="wiredesignz" date="1203098597"]Very clever thanks Elliot.
But I still like to display a string of * equivalent to the length of the real user password in the user account editor, this requires encrypt->decode to work.[/quote]

No it doesn't. Store an extra field that records the string length of the user's password, and display that. Update it whenever the user changes their password.

Always encrypt passwords with a salt, ALWAYS. This shouldn't even be debatable!
#13

[eluser]barbazul[/eluser]
A small contribution of a different secure alternative that has worked for me so far: Using PUBLIC/PRIVATE keys

It's not hard to obtain the packets that are sent through a network connection so, if the password "as is" is being sent, then anyone listening to that connection can obtain it.
Hashing the password before it's sent is not sufficient either because the hash will always look the same and the server will allways be expecting the same SHA1 (or md5) string.

So my solution is:
1. When the page is generated, create a public key and store it as flash data in the session. It has to be randomly generated in the moment and can have any length. The public key is sent to the browser (in javascript code or similar)
2. When the user enters his login information, before sending the password (the private key) on the net, append the public key at the end of the password and then MD5 the resulting string.
3. On the server, retrieve (and decrypt) the user's password, then append the public key to it and MD5 it. If both MD5s look the same, then the login is succesful
4. If the login is not succesful, generate a new public key and discard the previous one.

I think this is the most secure way
#14

[eluser]xwero[/eluser]
[quote author="barbazul" date="1203102440"]
It's not hard to obtain the packets that are sent through a network connection so, if the password "as is" is being sent, then anyone listening to that connection can obtain it.
[/quote]
I think the best solution for this security risk is using an https connection?
#15

[eluser]Elliot Haughin[/eluser]
Quote:No it doesn’t. Store an extra field that records the string length of the user’s password, and display that. Update it whenever the user changes their password.

Always encrypt passwords with a salt, ALWAYS. This shouldn’t even be debatable

Your dead right... I wouldn't even bother storing the length of the password, since it's a another 'clue' stored away...
Just give the user a blank box... it doesn't matter if it's got 9 stars in it or 8, or none...
The user isn't going to sit and count the number of stars in the box, in-fact, they probably don't care.

Quote:A small contribution of a different secure alternative that has worked for me so far: Using PUBLIC/PRIVATE keys

I think there's definitely a good point there.
But, this can all be done just using SSL, which means that all data sent back and forth from the client and server is automatically encrypted/decrypted.

The main problem is, if you do some form of hashing client-side on the password with a public key appended, it needs to be a 2-way encryption method so on the server side you can 'decrypt' the password/key hash to then test it against your secure _prep_password($password) database stored password.

And, if the encryption is performed client-side, a hacker could look at the hashing algorithm (because it has to be a js function or something), and work out how the 'hashed' transmitted password is built.
With this information, they can take the 'hashed' transmitted password, and reverse-code the clientside hashing script to produce the original transmitted password.

Which is where SSL really comes into its own... its fully encrypted transmission of requests is only possible to encode/decode with the SSL certificates located on your server, and married to your unique domain name.

Edit: xwero beat me to the SSL!

Ah, well, I hope this post explains why SSL is much better than any client-side hashing.
#16

[eluser]Phil Sturgeon[/eluser]
[quote author="Elliot Haughin" date="1203101327"]The fact of the matter is, if one method can be converted back to plain text 'some how' (with the encryption key), and the other method can't be converted back to plain text, then it is by very nature more secure.[/quote]

The point of an extra field storing the length is of course a good idea, but I will continue with my earlier point. If you consider yourself a hacker and you are writing a zombie script that will try to guess someones password. Think of the difference in the code that would be required... there are hardly any!

Hacking a SHA1 you would just guess words or autoincrement two strings that would check the pass and the key against the SHA1 hash... right? Thats pretty identical to autoincrementing a string to decrypt and see if it makes an actual word instead of random gibbery, even then you will get many false returns.

Cant see there being any logical difference there, but im open to suggestions.
#17

[eluser]Elliot Haughin[/eluser]
Quote:If you consider yourself a hacker and you are writing a zombie script that will try to guess someones password

First of all, this isn't how a hacker will work.
They will first and foremost discover everything possible about the application, server environment, and use this to discover possible vulnerabilities.

A 'zombie' script is always the last resort, as it takes an almost infinitely large amount of time, it's intensive, and the hacker will get blacklisted by iptables before they're even close to getting a password.

A sha1 salted hash can only be cracked with brute force...
To crack a sha1 hash with brute force, you may have to try 2 to the power 80 attempts. Way too much for any hacker to attempt.

Whereas, in the event of your encryption key being discovered (due to the 'clever' hacker probing your server environment, php version, ci version, and finding a vulnerability), a hacker could use the encryption key to get your passwords with no effort at all.

It's much much more likely you'll be hacked after an extensive recon task and research rather than through blind luck or brute force.
#18

[eluser]xwero[/eluser]
What i do using decodable passwords is to add a value to the password and cut it off when i display the password. So they have to find that second value too before decoding.
#19

[eluser]barbazul[/eluser]
@Elliot

looking at the hashing algorithm does not grant access.

Let me give you an example.
I use MD5 both on the client (javascript) and on the server


1. My server creates a key at random (i.e. qwer) and both stores it in the server and sends it to the client
2. User enters "mypass" on the browser and hits "Send"
3. javascript sends md5("mypass"+"qwer") to the server for validation
4. server recieves a weird hash. retrieves the real password for the user, (decrypts it if encrypted) and then appends "qwer" to the end and calculates its md5.
5. If it matches the weird hash sent then login worked fine.
6. Otherwise, the key is discarded and a new one is sent to the browser i.e. "zdrtfxc"

Now, the idea behind this is that on every request, the password sent will look different on each request even when its always the same. So if someone steals it from he packages being sent, it will be useless because the server will already be waiting for a different hash
#20

[eluser]Elliot Haughin[/eluser]
The whole process seems pretty secure... the only vulnerability is that the password stored in the database uses a 2-way encryption method, which is possible to decrypt... remove this vulnerability, and then it's properly secured.




Theme © iAndrew 2016 - Forum software by © MyBB