By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,538 Members | 927 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,538 IT Pros & Developers. It's quick & easy.

Encryption Question

P: n/a
I have a form where a user can change his password, but I'm confused
on how to prevent this from being transmitted in plain text.

Well, I know how not to transmit it in plain text - use any type of
encryption, but then the problem is, how do I decrypt it on the server
to store it?

If I use some type of key based encryption, the how do I get the key
to the client without it being intercepted, rendering the whole
process useless.

My question is, how can I set up secure password change functionality
on my site?

Mar 13 '07 #1
Share this Question
Share on Google+
25 Replies


P: n/a
On 13 Mar, 20:09, "egg...@gmail.com" <egg...@gmail.comwrote:
I have a form where a user can change his password, but I'm confused
on how to prevent this from being transmitted in plain text.

Well, I know how not to transmit it in plain text - use any type of
encryption, but then the problem is, how do I decrypt it on the server
to store it?

If I use some type of key based encryption, the how do I get the key
to the client without it being intercepted, rendering the whole
process useless.

My question is, how can I set up secure password change functionality
on my site?
easy answer: SSL
not so easy answer: you will need a javascript implementation of
either
a) (not so good) symmetric enc/decryption algo.
b) (more secure) RSA encryption with decent key bit size, and will
need to encrypt as little as possible, because it is 100x slower than
(a)

Assuming (b)
1. get your public key as a javascript string and send to client,
holding back the private on the server.
2. tell your user "please wait" while you use the freely available
RSA.js to encrypt the password field and copy it to a field called
encrypted-password
3. blank the password field
4. send the form off
5. capture $_POST['encrypted-password'] and decrypt using your private
key on the server side

google for "RSA javascript implmentation"

Mar 13 '07 #2

P: n/a
On 13 Mar, 20:09, "egg...@gmail.com" <egg...@gmail.comwrote:
I have a form where a user can change his password, but I'm confused
on how to prevent this from being transmitted in plain text.

Well, I know how not to transmit it in plain text - use any type of
encryption, but then the problem is, how do I decrypt it on the server
to store it?

If I use some type of key based encryption, the how do I get the key
to the client without it being intercepted, rendering the whole
process useless.

My question is, how can I set up secure password change functionality
on my site?
of course you do have the problem of how you allow your client to
login securely afterwards!
make sure you never send the password as plain text, use a one time
pad, along with multiple hashing to send an password hash, and
immediately expire the pad/hash on successful login.
Make sure you dont fall into the trap of sending a "password
equivalent" by simply hashing the password once with no one time pad,
using the same hashing algo that the db uses, using a check like

if ( $_POST['hashed_password']==$strHashedPasswordFromDatabase )
{
$auth = 1;
}

which I have seen!! That allows a sniffer to capture the hash on its
way to the server, and just use that each time.

Mar 13 '07 #3

P: n/a
eg****@gmail.com wrote:
I have a form where a user can change his password, but I'm confused
on how to prevent this from being transmitted in plain text.
Run the request over HTTP with SSL (HTTPS) not plain old HTTP.

JavaScript isn't relevant to the issue.

--
David Dorward <http://blog.dorward.me.uk/ <http://dorward.me.uk/>
Home is where the ~/.bashrc is
Mar 13 '07 #4

P: n/a
On Mar 13, 2:21 pm, "shimmyshack" <matt.fa...@gmail.comwrote:
On 13 Mar, 20:09, "egg...@gmail.com" <egg...@gmail.comwrote:
I have a form where a user can change his password, but I'm confused
on how to prevent this from being transmitted in plain text.
Well, I know how not to transmit it in plain text - use any type of
encryption, but then the problem is, how do I decrypt it on the server
to store it?
If I use some type of key based encryption, the how do I get the key
to the client without it being intercepted, rendering the whole
process useless.
My question is, how can I set up secure password change functionality
on my site?

easy answer: SSL
not so easy answer: you will need a javascript implementation of
either
a) (not so good) symmetric enc/decryption algo.
b) (more secure) RSA encryption with decent key bit size, and will
need to encrypt as little as possible, because it is 100x slower than
(a)

Assuming (b)
1. get your public key as a javascript string and send to client,
holding back the private on the server.
2. tell your user "please wait" while you use the freely available
RSA.js to encrypt the password field and copy it to a field called
encrypted-password
3. blank the password field
4. send the form off
5. capture $_POST['encrypted-password'] and decrypt using your private
key on the server side

google for "RSA javascript implmentation"
So the key to getting the new password from the client to the server,
while being able to decrypt it on the server is RSA encryption?

Mar 13 '07 #5

P: n/a
On 13 Mar, 21:48, "egg...@gmail.com" <egg...@gmail.comwrote:
On Mar 13, 2:21 pm, "shimmyshack" <matt.fa...@gmail.comwrote:
On 13 Mar, 20:09, "egg...@gmail.com" <egg...@gmail.comwrote:
I have a form where a user can change his password, but I'm confused
on how to prevent this from being transmitted in plain text.
Well, I know how not to transmit it in plain text - use any type of
encryption, but then the problem is, how do I decrypt it on the server
to store it?
If I use some type of key based encryption, the how do I get the key
to the client without it being intercepted, rendering the whole
process useless.
My question is, how can I set up secure password change functionality
on my site?
easy answer: SSL
not so easy answer: you will need a javascript implementation of
either
a) (not so good) symmetric enc/decryption algo.
b) (more secure) RSA encryption with decent key bit size, and will
need to encrypt as little as possible, because it is 100x slower than
(a)
Assuming (b)
1. get your public key as a javascript string and send to client,
holding back the private on the server.
2. tell your user "please wait" while you use the freely available
RSA.js to encrypt the password field and copy it to a field called
encrypted-password
3. blank the password field
4. send the form off
5. capture $_POST['encrypted-password'] and decrypt using your private
key on the server side
google for "RSA javascript implmentation"

So the key to getting the new password from the client to the server,
while being able to decrypt it on the server is RSA encryption?
yep, this is the same encryption that SSL is based on, you must have a
pair of keys, one of which you hold back and call "private" and one of
which you release to the client as javascript string. You use a js
implentation of RSA to encrypt the password string in browser memory
using the RSA key and then send the encrypted password back to the
server where the other key is waiting. You use php or some such to
load the private server-side key and decrypt the incoming POSTed
encrypted password.
It really does work and is strong if you use a 1024 bit key length -
at least, you should also save you private key password protected, so
that it cannot be easily stolen, and the php script which loads the
key should be the only place where the password is used unprotect the
private key as it is loaded for use in decryption.

Mar 13 '07 #6

P: n/a
On 13 Mar, 21:48, "egg...@gmail.com" <egg...@gmail.comwrote:
On Mar 13, 2:21 pm, "shimmyshack" <matt.fa...@gmail.comwrote:
On 13 Mar, 20:09, "egg...@gmail.com" <egg...@gmail.comwrote:
I have a form where a user can change his password, but I'm confused
on how to prevent this from being transmitted in plain text.
Well, I know how not to transmit it in plain text - use any type of
encryption, but then the problem is, how do I decrypt it on the server
to store it?
If I use some type of key based encryption, the how do I get the key
to the client without it being intercepted, rendering the whole
process useless.
My question is, how can I set up secure password change functionality
on my site?
easy answer: SSL
not so easy answer: you will need a javascript implementation of
either
a) (not so good) symmetric enc/decryption algo.
b) (more secure) RSA encryption with decent key bit size, and will
need to encrypt as little as possible, because it is 100x slower than
(a)
Assuming (b)
1. get your public key as a javascript string and send to client,
holding back the private on the server.
2. tell your user "please wait" while you use the freely available
RSA.js to encrypt the password field and copy it to a field called
encrypted-password
3. blank the password field
4. send the form off
5. capture $_POST['encrypted-password'] and decrypt using your private
key on the server side
google for "RSA javascript implmentation"

So the key to getting the new password from the client to the server,
while being able to decrypt it on the server is RSA encryption?
I suppose it might be worth saying that in order for your SSL or
javascript based method to work in a truly secure fashion, you will
have to take steps to ensure your site is not vulnerable to XSS on any
page, and that it is protected from SQL injection, if these or other
vulnerabilities exist in your app layer, no amount of secure
transportation will help.
(most sites have some form of this I would say, so make sure yours
doesnt!)

For instance, you have a page which takes as one value the URL where
you were passed along in the URL to your "contact me if there was an
error with this page" where it is included in the body somewhere. With
a little modification it is possible to inject a piece of javascript
which calls a payload from another server. This payload rewrites the
page to add two further fields "login" and "password" so you can be
credited with bonus points or whatever for reporting the trouble, the
password is nicked and posting to attacker.com before posting the
correct data on to the right place.

This exact problem exists on an ISPs portal page that shall remain
nameless. I was told that due to "random seeding of our SSL sessions
the attack is not possible".
Lesson XSS gets transported and included into the SSL encrypted HTTP
session, so don;t regard any system as secure until the last remaining
vulnerability has been identified - however you do seem to have
security in mind which is great.

While David is right, SSL is best, in general there is a trade off
between getting creative when there are perfectly good tried and
tested open source security solutions out there already, and being
"satisfied" that just because you use one of them you are secure. In
this case javascript is secure provided you stick to a tight
implementation.

Mar 13 '07 #7

P: n/a
David Dorward wrote:
egg...@gmail.com wrote:
>I have a form where a user can change his password,
but I'm confused on how to prevent this from being
transmitted in plain text.

Run the request over HTTP with SSL (HTTPS) not plain old HTTP.
JavaScript isn't relevant to the issue.
A plain javascript solution is possible without need for HTTPS.

http://groups.google.com/group/comp....6d1191285a15a4

- let user type new password
- encrypt it using javascript (see link above)
- send encrypted string over HTTP and store it
- re-authentication based on same algorithm (handled at server or
client)

The algorithm of the script above corresponds to the default crypt
function on UNIX. This means that the password must be stored as an
encrypted string too - which is certainly recommended, and it seems
that the original poster isn't doing this. A safe password encryption
must always be non-reversible.

--
Bart

Mar 14 '07 #8

P: n/a
On 14 Mar, 12:06, "Bart Van der Donck" <b...@nijlen.comwrote:
David Dorward wrote:
egg...@gmail.com wrote:
I have a form where a user can change his password,
but I'm confused on how to prevent this from being
transmitted in plain text.
Run the request over HTTP with SSL (HTTPS) not plain old HTTP.
JavaScript isn't relevant to the issue.

A plain javascript solution is possible without need for HTTPS.

http://groups.google.com/group/comp....6d1191285a15a4

- let user type new password
- encrypt it using javascript (see link above)
- send encrypted string over HTTP and store it
- re-authentication based on same algorithm (handled at server or
client)

The algorithm of the script above corresponds to the default crypt
function on UNIX. This means that the password must be stored as an
encrypted string too - which is certainly recommended, and it seems
that the original poster isn't doing this. A safe password encryption
must always be non-reversible.

--
Bart

Bart, you method solves the later stages when the OPs user needs to
authenticate, preventing capture of his newly changed password as the
user does so.
The OP wanted to know how he could /change/ his password. This
requires that the server has no knowledge of the password it is about
to receive and so the encryption must be reversible, which is where
sym. or asym. enc. comes in, however sym. cant be used because this
would require that the key be sent to the user-agent, so it has to be
asym. and there are indeed js implementations of this. No link was
provided though because I felt google would suffice.

Mar 14 '07 #9

P: n/a
On Mar 14, 5:06 am, "Bart Van der Donck" <b...@nijlen.comwrote:
David Dorward wrote:
egg...@gmail.com wrote:
I have a form where a user can change his password,
but I'm confused on how to prevent this from being
transmitted in plain text.
Run the request over HTTP with SSL (HTTPS) not plain old HTTP.
JavaScript isn't relevant to the issue.

A plain javascript solution is possible without need for HTTPS.

http://groups.google.com/group/comp....6d1191285a15a4

- let user type new password
- encrypt it using javascript (see link above)
- send encrypted string over HTTP and store it
- re-authentication based on same algorithm (handled at server or
client)

The algorithm of the script above corresponds to the default crypt
function on UNIX. This means that the password must be stored as an
encrypted string too - which is certainly recommended, and it seems
that the original poster isn't doing this. A safe password encryption
must always be non-reversible.

--
Bart
Correct, right now, I'm saving the password as plain text on the
server. When the user signs in their password is sha1 hashed by
javascript then sent to the server where the server password is then
sha1 hashed and compared to what the client sent.

So what your proposing is when the user signs up, hash the password as
usual, but save it in that state to the server.

Then when the user signs in, hash their password, send to the server
and then compare? Wouldn't that be sending the same hash to the server
each time, how's the better then just sending plain text? that is
plain text in essence...

Please get back to me

Mar 14 '07 #10

P: n/a
On 14 Mar, 14:52, "egg...@gmail.com" <egg...@gmail.comwrote:
On Mar 14, 5:06 am, "Bart Van der Donck" <b...@nijlen.comwrote:
David Dorward wrote:
egg...@gmail.com wrote:
>I have a form where a user can change his password,
>but I'm confused on how to prevent this from being
>transmitted in plain text.
Run the request over HTTP with SSL (HTTPS) not plain old HTTP.
JavaScript isn't relevant to the issue.
A plain javascript solution is possible without need for HTTPS.
http://groups.google.com/group/comp....6d1191285a15a4
- let user type new password
- encrypt it using javascript (see link above)
- send encrypted string over HTTP and store it
- re-authentication based on same algorithm (handled at server or
client)
The algorithm of the script above corresponds to the default crypt
function on UNIX. This means that the password must be stored as an
encrypted string too - which is certainly recommended, and it seems
that the original poster isn't doing this. A safe password encryption
must always be non-reversible.
--
Bart

Correct, right now, I'm saving the password as plain text on the
server. When the user signs in their password is sha1 hashed by
javascript then sent to the server where the server password is then
sha1 hashed and compared to what the client sent.

So what your proposing is when the user signs up, hash the password as
usual, but save it in that state to the server.

Then when the user signs in, hash their password, send to the server
and then compare? Wouldn't that be sending the same hash to the server
each time, how's the better then just sending plain text? that is
plain text in essence...

Please get back to me
your instinct is spot on, sending the same hash each time would be
what I earlier referred to as a "password equivalent" which is why
that's NOT what Bart is suggesting.
Look at the code he points to, it uses a salt.

Client C requests login page
Server S sends login page, with md5.js and sha1.js - _and_ in hidden
input or wherever, a random salt, server also stores salt in session

C inputs password and presses submit, the javascript md5(p) and
concatenates the salt and then sha1( md5(p) + salt ), blanks the
password field(so the plain text isnt sent) and sends hashed
password_data to server

server knows what salt it sent earlier so S just retrieves the
password from the database which is stored in some hashed form (lets
say as md5), so dbpass = md5(p)
then S knows that if $_POST['password_data'] == sha1(dbpass + salt)
then the user must have typed the good password
Server then immediately deletes the salt from the session, so that a
replay attack cannot occur from a passive sniffer (man-in-the-middle)
reposting the same data.
Notice at no point is the actual password stored, instead it is stored
in the database as md5 hash.
This is so if anyone steals any data they cannot obtain the password,
since md5, like sha1 is irreversible.

Also you dont have to use md5 in database, you could use sha1 in the
database, so now the client just needs to be sent
sha1.js and can do sha1( sha1(p) + salt)
and server checks to see if this is equal to
sha1( $_POST['password_data'] + salt )
This is what I referred to as multiple hashing - using same algo,
which is super fast and in fact you can hash a few times if you wish,
as long as the server and client agree on how many times that was.

What you have to understand is that none of this helps you when
*changing* the password. Because when you change the password the
server has no stored password hash in the database, for this you need
assymetirc (reversible) encryption as dicussed earlier.

Mar 14 '07 #11

P: n/a
On 14 Mar, 18:22, "shimmyshack" <matt.fa...@gmail.comwrote:
On 14 Mar, 14:52, "egg...@gmail.com" <egg...@gmail.comwrote:
On Mar 14, 5:06 am, "Bart Van der Donck" <b...@nijlen.comwrote:
David Dorward wrote:
egg...@gmail.com wrote:
I have a form where a user can change his password,
but I'm confused on how to prevent this from being
transmitted in plain text.
Run the request over HTTP with SSL (HTTPS) not plain old HTTP.
JavaScript isn't relevant to the issue.
A plain javascript solution is possible without need for HTTPS.
>http://groups.google.com/group/comp....6d1191285a15a4
- let user type new password
- encrypt it using javascript (see link above)
- send encrypted string over HTTP and store it
- re-authentication based on same algorithm (handled at server or
client)
The algorithm of the script above corresponds to the default crypt
function on UNIX. This means that the password must be stored as an
encrypted string too - which is certainly recommended, and it seems
that the original poster isn't doing this. A safe password encryption
must always be non-reversible.
--
Bart
Correct, right now, I'm saving the password as plain text on the
server. When the user signs in their password is sha1 hashed by
javascript then sent to the server where the server password is then
sha1 hashed and compared to what the client sent.
So what your proposing is when the user signs up, hash the password as
usual, but save it in that state to the server.
Then when the user signs in, hash their password, send to the server
and then compare? Wouldn't that be sending the same hash to the server
each time, how's the better then just sending plain text? that is
plain text in essence...
Please get back to me

your instinct is spot on, sending the same hash each time would be
what I earlier referred to as a "password equivalent" which is why
that's NOT what Bart is suggesting.
Look at the code he points to, it uses a salt.

Client C requests login page
Server S sends login page, with md5.js and sha1.js - _and_ in hidden
input or wherever, a random salt, server also stores salt in session

C inputs password and presses submit, the javascript md5(p) and
concatenates the salt and then sha1( md5(p) + salt ), blanks the
password field(so the plain text isnt sent) and sends hashed
password_data to server

server knows what salt it sent earlier so S just retrieves the
password from the database which is stored in some hashed form (lets
say as md5), so dbpass = md5(p)

then S knows that if $_POST['password_data'] == sha1(dbpass + salt)
then the user must have typed the good password
Server then immediately deletes the salt from the session, so that a
replay attack cannot occur from a passive sniffer (man-in-the-middle)
reposting the same data.

Notice at no point is the actual password stored, instead it is stored
in the database as md5 hash.
This is so if anyone steals any data they cannot obtain the password,
since md5, like sha1 is irreversible.

Also you dont have to use md5 in database, you could use sha1 in the
database, so now the client just needs to be sent
sha1.js and can do sha1( sha1(p) + salt)
and server checks to see if this is equal to
sha1( $_POST['password_data'] + salt )
This is what I referred to as multiple hashing - using same algo,
which is super fast and in fact you can hash a few times if you wish,
as long as the server and client agree on how many times that was.

What you have to understand is that none of this helps you when
*changing* the password. Because when you change the password the
server has no stored password hash in the database, for this you need
assymetirc (reversible) encryption as dicussed earlier.
Just in case you are thinking aha, I can now be secure, nope. If you
do not use SSL, then the man-in-the-middle - who might in fact be a
foxy girl - who is now angry at being thwarted earlier, can simply
sniff the session authentication token that you use to maintain the
logged in status, which gets sent between the server and client on
each request, and simply post *that* to you instead.
This gives her access to the user's account without knowing the
password. You will have a very hard time coding something which
*prevents* this girl piggy-backing on the session.
In fact passive sniffing is theoretically preventable if you send a
one time pad (salt) with every request for private data.
Active sniffing - where girl-in-the-middle receives the server data
and prevents real user from receiving it, and simply intercepts and
captures all traffic from then on, is not preventable without using
asymmetric encryption to encrypt the session cookie IMHO.

Mar 14 '07 #12

P: n/a
egg...@gmail.com wrote:
[...]
Correct, right now, I'm saving the password as plain text on the
server.
You shouldn't do that in a robust authentication model.
When the user signs in their password is sha1 hashed by
javascript then sent to the server where the server password is then
sha1 hashed and compared to what the client sent.
SHA-1 is safe, so the transmission should be protected by this measure
(which is probably why you did it). HTTPS wouldn't add much security
here, though it adds a (perceived!) feeling of safety for the user,
which you might also take into account as a valid argument. Your real
weak point is that the password resides in plaintext on the server.
So what your proposing is when the user signs up, hash the password as
usual, but save it in that state to the server.
Exactly - it adds one level of security. And your server program
doesn't need to be bothered with SHA-1 encryptions all the time, which
might become quite CPU-consuming depending on the circumstances.
Then when the user signs in, hash their password, send to the server
and then compare? Wouldn't that be sending the same hash to the server
each time, how's the better then just sending plain text? that is
plain text in essence...
Normal authentication:

- let user type his password, encrypt it
- do something like: login.asp?EncPW=gH4tGhKLNx
- compare gH4tGhKLNx to stored string to find out if authentication
has succeeded

Changing password:

- let user type the current password and his new requested password,
encrypt both
- do something like: getnewpass.asp?
oldEncPW=gH4tGhKLNx&newEncPW=yHjke4c5Wu
- compare oldEncPW to stored string; if it matches, then delete old
string and store the new one

No server encryption or HTTPS is needed in this scenario; it would not
add any additional security. You could use your favourite (one-way!)
encryption technology from javascript only.

Alternatively, you could send plaintext too. Most authentication
models do this, and it's okay, but only as long as the transmission
takes place over HTTPS. In your case, HTTPS has no real effect because
the password is already SHA-1 encrypted.

Hope this helps,

--
Bart

Mar 14 '07 #13

P: n/a
On 14 Mar, 19:10, "Bart Van der Donck" <b...@nijlen.comwrote:
egg...@gmail.com wrote:
[...]
Correct, right now, I'm saving the password as plain text on the
server.

You shouldn't do that in a robust authentication model.
When the user signs in their password is sha1 hashed by
javascript then sent to the server where the server password is then
sha1 hashed and compared to what the client sent.

SHA-1 is safe, so the transmission should be protected by this measure
(which is probably why you did it). HTTPS wouldn't add much security
here, though it adds a (perceived!) feeling of safety for the user,
which you might also take into account as a valid argument. Your real
weak point is that the password resides in plaintext on the server.
So what your proposing is when the user signs up, hash the password as
usual, but save it in that state to the server.

Exactly - it adds one level of security. And your server program
doesn't need to be bothered with SHA-1 encryptions all the time, which
might become quite CPU-consuming depending on the circumstances.
Then when the user signs in, hash their password, send to the server
and then compare? Wouldn't that be sending the same hash to the server
each time, how's the better then just sending plain text? that is
plain text in essence...

Normal authentication:

- let user type his password, encrypt it
- do something like: login.asp?EncPW=gH4tGhKLNx
- compare gH4tGhKLNx to stored string to find out if authentication
has succeeded

Changing password:

- let user type the current password and his new requested password,
encrypt both
- do something like: getnewpass.asp?
oldEncPW=gH4tGhKLNx&newEncPW=yHjke4c5Wu
- compare oldEncPW to stored string; if it matches, then delete old
string and store the new one

thus the man-in-the-middle would now know the password hash being
stored in the database.

Now he can request to login, and send
sha1( password_hash_he_sniffed + salt)
now despite not knowing the password the attacker gets in from that
point onward.

You cannot securely change a password using irreversible hashes
without asym. enc.
>
No server encryption or HTTPS is needed in this scenario; it would not
add any additional security. You could use your favourite (one-way!)
encryption technology from javascript only.

Alternatively, you could send plaintext too. Most authentication
models do this, and it's okay, but only as long as the transmission
takes place over HTTPS. In your case, HTTPS has no real effect because
the password is already SHA-1 encrypted.

Hope this helps,

--
Bart

Mar 14 '07 #14

P: n/a
Bart Van der Donck wrote:
[...]
In your case, HTTPS has no real effect because the password
is already SHA-1 encrypted.
Sorry, that was not correct. You need HTTPS anyway in order to crypt
the transmission itself, whether the query string is encrypted or not.
Otherwise one could eavesdrop the URL to get the SHA-1 encrypted
string (not the password), which could be successfully used against
the server.

--
Bart

Mar 14 '07 #15

P: n/a
shimmyshack wrote:
On 14 Mar, 19:10, "Bart Van der Donck" <b...@nijlen.comwrote:
Changing password:
- let user type the current password and his
new requested password,
encrypt both
- do something like: getnewpass.asp?
oldEncPW=gH4tGhKLNx&newEncPW=yHjke4c5Wu
- compare oldEncPW to stored string; if it matches, then
delete old string and store the new one

thus the man-in-the-middle would now know the password hash
being stored in the database.

Now he can request to login, and send
sha1( password_hash_he_sniffed + salt)
now despite not knowing the password the attacker gets in
from that point onward.
Yes, HTTPS should be added. See my reply to myself some minutes ago.
For the rest, my model should be secure if one uses a one-way
encryption in javascript, both for the authentication as for the
password change.

Of course, once HTTPS is there, one could send the password in
plaintext as well, and let the server application encrypt it before
storing it (which would be the more traditional authentication
scheme).

--
Bart

Mar 14 '07 #16

P: n/a
On 14 Mar, 20:07, "Bart Van der Donck" <b...@nijlen.comwrote:
shimmyshack wrote:
On 14 Mar, 19:10, "Bart Van der Donck" <b...@nijlen.comwrote:
Changing password:
- let user type the current password and his
new requested password,
encrypt both
- do something like: getnewpass.asp?
oldEncPW=gH4tGhKLNx&newEncPW=yHjke4c5Wu
- compare oldEncPW to stored string; if it matches, then
delete old string and store the new one
thus the man-in-the-middle would now know the password hash
being stored in the database.
Now he can request to login, and send
sha1( password_hash_he_sniffed + salt)
now despite not knowing the password the attacker gets in
from that point onward.

Yes, HTTPS should be added. See my reply to myself some minutes ago.
For the rest, my model should be secure if one uses a one-way
encryption in javascript, both for the authentication as for the
password change.

Of course, once HTTPS is there, one could send the password in
plaintext as well, and let the server application encrypt it before
storing it (which would be the more traditional authentication
scheme).

--
Bart
I did see your reply, don't worry :)
I am not sure that one way hashing is able to secure a password
change, obviously just because I cannot see your point doesnt mean you
are wrong, but if you can clarify how it is possible to send a hashed
password which the server doesnt already know and store /that/ hash in
a way that cannot be replayed I'd be interested. It would certainly
save some time for me, because I would not surrent use such a scheme
to send a change ;)
matt

Mar 14 '07 #17

P: n/a
shimmyshack wrote:
I am not sure that one way hashing is able to secure a
password change, obviously just because I cannot see
your point doesnt mean you are wrong, but if you can
clarify how it is possible to send a hashed password
which the server doesnt already know and store /that/
hash in a way that cannot be replayed I'd be interested.
It would certainly save some time for me, because I would
not surrent use such a scheme to send a change ;)
One-way encryption from client on beforehand is secure to change the
password on one Conditio, which is that the user must know the
previous (encrypted) password.

E.g. if one posts the following to newpass.php:
oldEncPW=gH4tGhKLNx
newEncPW=yHjke4c5Wu

Then compare the old (stored) string to the sent 'gH4tGhKLNx'. If it
matches, replace it by 'yHjke4c5Wu'. No encryption needed at server
side, and safe if it goes over HTTPS.

(One common alternative that comes to mind is to use a cookie where
the old password is stored, so the user doesn't need to retype it when
he requests to change it.)

--
Bart

Mar 14 '07 #18

P: n/a
Bart Van der Donck wrote:
<snip>
One-way encryption from client on beforehand is secure
to change the password on one Conditio, which is that
the user must know the previous (encrypted) password.

E.g. if one posts the following to newpass.php:
oldEncPW=gH4tGhKLNx
newEncPW=yHjke4c5Wu

Then compare the old (stored) string to the sent
'gH4tGhKLNx'. If it matches, replace it by 'yHjke4c5Wu'.
No encryption needed at server side, and safe if it goes
over HTTPS.

(One common alternative that comes to mind is to use a
cookie where the old password is stored, so the user doesn't
need to retype it when he requests to change it.)
Isn't the problem with sending the password in plain text over HTTP that
someone may intercept the traffic and so acquire the password for later
use in gaining access that they are not entitled to?

However, if a 'hash' of the password is sent in plain text over HTTP, and
all the server knows is the 'hash' of the password, has the situation
really changed? What is to stop someone who knows the 'hash' of the
password inserting it into the appropriate location in an HTTP request
(by any of numerous means, including the executing of alien javascript on
the logon page)? Wouldn't the server recognise the intercepted 'hash' as
easily as it may have recognised the original password?

The advantage of HTTPS is that someone intercepting the HTTP traffic is
not going to find it easy to make any sense of what they observe.

Richard.

Mar 14 '07 #19

P: n/a
On 14 Mar, 22:21, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:
Bart Van der Donck wrote:
<snip>
One-way encryption from client on beforehand is secure
to change the password on one Conditio, which is that
the user must know the previous (encrypted) password.
E.g. if one posts the following to newpass.php:
oldEncPW=gH4tGhKLNx
newEncPW=yHjke4c5Wu
Then compare the old (stored) string to the sent
'gH4tGhKLNx'. If it matches, replace it by 'yHjke4c5Wu'.
No encryption needed at server side, and safe if it goes
over HTTPS.
(One common alternative that comes to mind is to use a
cookie where the old password is stored, so the user doesn't
need to retype it when he requests to change it.)

Isn't the problem with sending the password in plain text over HTTP that
someone may intercept the traffic and so acquire the password for later
use in gaining access that they are not entitled to?

However, if a 'hash' of the password is sent in plain text over HTTP, and
all the server knows is the 'hash' of the password, has the situation
really changed? What is to stop someone who knows the 'hash' of the
password inserting it into the appropriate location in an HTTP request
(by any of numerous means, including the executing of alien javascript on
the logon page)? Wouldn't the server recognise the intercepted 'hash' as
easily as it may have recognised the original password?

The advantage of HTTPS is that someone intercepting the HTTP traffic is
not going to find it easy to make any sense of what they observe.

Richard.
yes I fear that this is NOT secure. Take for instance the condition
that the user knows the previous password. The old password is stored
in the mysql database as SHA1 hash. (let us say for argument's sake
the old password was 'fred' and that the new is 'newpassword'
so the database contains the sha1 hash
$db_data = sha1('fred')
now the user typed in fred which with a salt was sha1'd by the client
and sent to the server.
js-sha1(salt+sha1('fred'))
then sends this as hashed_data
the server must check that the user entered fred, but can only do this
by copying the procedure
server-sha1($salt . $db_data ) and seeing if it is equal to what was
in the $_POST var
$_POST['hashed_data'].

Now what you are proposing is that the server checks this and when the
user has indeed verified that they know the old password, you then
_replace the old hash with sha1('newpassword')

now anyone listening to the traffic as Richard says now knows the new
hash they have eaves dropped
sha1('newpassword')

so the attacker just requests the logon page, gets given a new salt
and can now send this POST data (using some proxy or other or a header
editor)
$_POST['hashed_data'] = sha1( newsalt+sha1('newpassword') )
the attacker doesnt need to know the password.

The server accepts this and compares it against the database entry by
the smae method as before
server-sha1($newsalt . $new_db_data )
where $new_db_data is sha1('newpassword')

they match and the attacker gets in
This shows that there is no security in sending the sha1(password)
where this string will then be directly stored in the database. I for
one _never use_ one way hashing to *change* passwords, only to
authenticate an existing one which *can* be secure I agree with you
there!
Mar 14 '07 #20

P: n/a
shimmyshack wrote:
On 14 Mar, 22:21, "Richard Cornford" wrote:
>Bart Van der Donck wrote:
>>One-way encryption from client on beforehand is secure
to change the password on one Conditio, which is that
the user must know the previous (encrypted) password.
>>E.g. if one posts the following to newpass.php:
oldEncPW=gH4tGhKLNx
newEncPW=yHjke4c5Wu
>>Then compare the old (stored) string to the sent
'gH4tGhKLNx'. If it matches, replace it by 'yHjke4c5Wu'.
No encryption needed at server side, and safe if it goes
over HTTPS.
yes I fear that this is NOT secure. Take for instance the
condition that the user knows the previous password.
It's the same as saying that the application can trust the user.
Anyone who knows the previous password, may change it to a new one.
The old password is stored in the mysql database as SHA1
hash. (let us say for argument's sake the old password was
'fred' and that the new is 'newpassword' so the database
contains the sha1 hash
$db_data = sha1('fred')
now the user typed in fred which with a salt was sha1'd by
the client and sent to the server.
js-sha1(salt+sha1('fred'))
then sends this as hashed_data
the server must check that the user entered fred, but can
only do this by copying the procedure server-sha1($salt .
$db_data ) and seeing if it is equal to what was
in the $_POST var $_POST['hashed_data'].
In my scheme, the server doesn't know anything about the plaintext
password because nothing plaintext is sent from js or received at
server. All it gets is the already js-hashed string to do stuff with.
The server doesn't do any hashing, all it does is compare the hashed
string to what's stored.

- user types current password
- js hashes it (irreversibly)
- js sends only hash to server, not plaintext (yes, over HTTPS)
- server compares if it matches to its own stored (hashed) string
- if it matches, authentication succeeded (so he can enter application
or change password etc.)

I don't see a leak in this scheme, but, please, I'ld be very happy to
know, I'm running a whole university based on this :-)
Now what you are proposing is that the server checks this
and when the user has indeed verified that they know the old
password, you then _replace the old hash with sha1('newpassword')
Yes, with sha1('newpassword') encrypted by javascript.
now anyone listening to the traffic as Richard says now knows
the new hash they have eaves dropped sha1('newpassword')
You're right, but that's why the traffic should go over HTTPS. Then
this can't happen.
so the attacker just requests the logon page, gets given a
new salt and can now send this POST data (using some proxy or
other or a header editor)
$_POST['hashed_data'] = sha1( newsalt+sha1('newpassword') )
the attacker doesnt need to know the password.
Okay, but he does need to know the hashed string. I don't see how he
can get that information if the traffic goes over HTTPS.
The server accepts this and compares it against the database
entry by the smae method as before
server-sha1($newsalt . $new_db_data )
where $new_db_data is sha1('newpassword')
they match and the attacker gets in
Yes he's in then, but he must always know the hashed password for
that. Sure, if that is known, one can get in. But I don't see how an
attacker could get his hands on it, assumed that the traffic goes over
HTTPS.

--
Bart

Mar 15 '07 #21

P: n/a
On Mar 15, 10:57 am, "Bart Van der Donck" <b...@nijlen.comwrote:
shimmyshack wrote:
On 14 Mar, 22:21, "Richard Cornford" wrote:
Bart Van der Donck wrote:
>One-way encryption from client on beforehand is secure
to change the password on one Conditio, which is that
the user must know the previous (encrypted) password.
>E.g. if one posts the following to newpass.php:
oldEncPW=gH4tGhKLNx
newEncPW=yHjke4c5Wu
>Then compare the old (stored) string to the sent
'gH4tGhKLNx'. If it matches, replace it by 'yHjke4c5Wu'.
No encryption needed at server side, and safe if it goes
over HTTPS.
yes I fear that this is NOT secure. Take for instance the
condition that the user knows the previous password.

It's the same as saying that the application can trust the user.
Anyone who knows the previous password, may change it to a new one.
The old password is stored in the mysql database as SHA1
hash. (let us say for argument's sake the old password was
'fred' and that the new is 'newpassword' so the database
contains the sha1 hash
$db_data = sha1('fred')
now the user typed in fred which with a salt was sha1'd by
the client and sent to the server.
js-sha1(salt+sha1('fred'))
then sends this as hashed_data
the server must check that the user entered fred, but can
only do this by copying the procedure server-sha1($salt .
$db_data ) and seeing if it is equal to what was
in the $_POST var $_POST['hashed_data'].

In my scheme, the server doesn't know anything about the plaintext
password because nothing plaintext is sent from js or received at
server. All it gets is the already js-hashed string to do stuff with.
The server doesn't do any hashing, all it does is compare the hashed
string to what's stored.

- user types current password
- js hashes it (irreversibly)
- js sends only hash to server, not plaintext (yes, over HTTPS)
- server compares if it matches to its own stored (hashed) string
- if it matches, authentication succeeded (so he can enter application
or change password etc.)

I don't see a leak in this scheme, but, please, I'ld be very happy to
know, I'm running a whole university based on this :-)
Now what you are proposing is that the server checks this
and when the user has indeed verified that they know the old
password, you then _replace the old hash with sha1('newpassword')

Yes, with sha1('newpassword') encrypted by javascript.
now anyone listening to the traffic as Richard says now knows
the new hash they have eaves dropped sha1('newpassword')

You're right, but that's why the traffic should go over HTTPS. Then
this can't happen.
so the attacker just requests the logon page, gets given a
new salt and can now send this POST data (using some proxy or
other or a header editor)
$_POST['hashed_data'] = sha1( newsalt+sha1('newpassword') )
the attacker doesnt need to know the password.

Okay, but he does need to know the hashed string. I don't see how he
can get that information if the traffic goes over HTTPS.
The server accepts this and compares it against the database
entry by the smae method as before
server-sha1($newsalt . $new_db_data )
where $new_db_data is sha1('newpassword')
they match and the attacker gets in

Yes he's in then, but he must always know the hashed password for
that. Sure, if that is known, one can get in. But I don't see how an
attacker could get his hands on it, assumed that the traffic goes over
HTTPS.

--
Bart
Sure Bart, my bad, I didn't understand your previous posts probably :)
- yes HTTPS *must* be used to send the *new* password hashed or not.
Then your scheme is FINE! Your university is safe - on a few
conditions!
The OP doesn't appear to have SSL and so I wanted to make sure that he
knew that without SSL you cannot either set a new password, or change
a password without SSL using irreversible hashes without revealing
enough info to passive or active sniffers to compromise the exchange -
although here even I am prepared for someone cleverer than me - there
are many of them - to show me how!!

The conditions I refer to are "nowhere on that domain/site can there
be an XSS vulnerability". SSL cannot help you then, as the javascript
hash can be stolen before/after it is sent via HTTPS, this is the
situation with most websites from time to time; for instance there is
a google.com XSS doing the rounds at the moment, which allows stuff to
be stolen from within the application, it doesnt care how the
transport is made, once that javascript makes its way inside the app
it acts when in the browser.
Yeah Bart, I agree, using HTTPS to send the hashed new password as a
POST payload is shall we say "safest".
Man, the OP must wish he never asked!

Mar 15 '07 #22

P: n/a
Richard Cornford wrote:
Isn't the problem with sending the password in plain text
over HTTP that someone may intercept the traffic and so
acquire the password for later use in gaining access that
they are not entitled to?
Precisely.
However, if a 'hash' of the password is sent in plain text
over HTTP, and all the server knows is the 'hash' of the
password, has the situation really changed?
No. It's the programmer's choice to let the client perform the
encryption in this scenario. Sure, one could send the password in
plaintext too, and let server encrypt it. This would be a more
traditional approach, and, as long as it uses HTTPS, an equally secure
scheme.
What is to stop someone who knows the 'hash' of the
password inserting it into the appropriate location in an
HTTP request (by any of numerous means, including the
executing of alien javascript on the logon page)? Wouldn't
the server recognise the intercepted 'hash' as easily as
it may have recognised the original password?
Yes.
The advantage of HTTPS is that someone intercepting the
HTTP traffic is not going to find it easy to make any
sense of what they observe.
Understatement - HTTPS is secure. But its importance should not be
exaggerated and well scoped. HTTPS does not take care of your safety;
it only secures the transmission itself (cfr. its "tunnel"-
terminology) which is only a small part of the total security picture
of an application.

Shimmyshack is very right to state that most of the troubles aren't
caused by not applying HTTPS, but by what happens after the sensitive
data has arrived at the server. After all, traffic can only be
intercepted at each hop from client to server, and, apart from the W/
LAN, these hops are ISP's routers that are mostly strictly secured.

Tons of sensitive data travel unencrypted this way: POP3 for email,
default UNIX (htaccess) authentication, passwords of internet
subscriptions, FTP, Telnet passwords, (XML) message sets, etc.

--
Bart

Mar 15 '07 #23

P: n/a
On 15 Mar, 21:14, "Bart Van der Donck" <b...@nijlen.comwrote:
Richard Cornford wrote:
Isn't the problem with sending the password in plain text
over HTTP that someone may intercept the traffic and so
acquire the password for later use in gaining access that
they are not entitled to?

Precisely.
However, if a 'hash' of the password is sent in plain text
over HTTP, and all the server knows is the 'hash' of the
password, has the situation really changed?

No. It's the programmer's choice to let the client perform the
encryption in this scenario. Sure, one could send the password in
plaintext too, and let server encrypt it. This would be a more
traditional approach, and, as long as it uses HTTPS, an equally secure
scheme.
What is to stop someone who knows the 'hash' of the
password inserting it into the appropriate location in an
HTTP request (by any of numerous means, including the
executing of alien javascript on the logon page)? Wouldn't
the server recognise the intercepted 'hash' as easily as
it may have recognised the original password?

Yes.
The advantage of HTTPS is that someone intercepting the
HTTP traffic is not going to find it easy to make any
sense of what they observe.

Understatement - HTTPS is secure. But its importance should not be
exaggerated and well scoped. HTTPS does not take care of your safety;
it only secures the transmission itself (cfr. its "tunnel"-
terminology) which is only a small part of the total security picture
of an application.

Shimmyshack is very right to state that most of the troubles aren't
caused by not applying HTTPS, but by what happens after the sensitive
data has arrived at the server. After all, traffic can only be
intercepted at each hop from client to server, and, apart from the W/
LAN, these hops are ISP's routers that are mostly strictly secured.

Tons of sensitive data travel unencrypted this way: POP3 for email,
default UNIX (htaccess) authentication, passwords of internet
subscriptions, FTP, Telnet passwords, (XML) message sets, etc.

--
Bart
Then there's the problem of the big-brother IT dept. that installs pre-
trusted certs onto PCs, so they can proxy the SSL, de/re-encrypting it
at the border!

Mar 16 '07 #24

P: n/a
Bart Van der Donck wrote:
Richard Cornford wrote:
>Isn't the problem with sending the password in plain text
over HTTP that someone may intercept the traffic and so
acquire the password for later use in gaining access that
they are not entitled to?

Precisely.
>However, if a 'hash' of the password is sent in plain text
over HTTP, and all the server knows is the 'hash' of the
password, has the situation really changed?

No. It's the programmer's choice to let the client perform
the encryption in this scenario. Sure, one could send the
password in plaintext too, and let server encrypt it. This
would be a more traditional approach, and, as long as it
uses HTTPS, an equally secure scheme.
<snip>

If we accept that HTTPS is providing a secure tunnel for transmission of
the password information from the client to the server and so eliminating
the risk of interception we have two points where the password
information can be picked up. At the client (which we cannot do much
about in most cases) and at the server. You have suggested that it is not
a good idea for the passwords to be stored in plain text on the server. I
would agree with that; someone seeing the password on the server could
easily go to a client and enter that password and be logged on with the
privileges granted to that password (assuming that they also know the
user name in question). So the value stored on the server is the
post-hash equivalent of the password.

However, if you hash on client prior to transmission and compare what
arrives with the stored hashed version don't you now have the problem
that someone seeing the hashed version on the server can take that and
insert it on the client at the point where the client side hashing
outputs, pump it into our 'safe' HTTPS tunnel and have it recognised when
it comes out of the other end? While if the hashing is done on the
server, and it is the password text that is transmitted, seeing the
post-hash version on the server will not tell someone what password text
they could be inserting on the client, and the only point where they
could insert the post-hash version to gain access is in the code that
does the password verification on the server. And if they can get at (and
influence) that code they don't actually need to know any passwords at
all.

Richard.

Mar 17 '07 #25

P: n/a
On 17 Mar, 12:53, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:
Bart Van der Donck wrote:
Richard Cornford wrote:
Isn't the problem with sending the password in plain text
over HTTP that someone may intercept the traffic and so
acquire the password for later use in gaining access that
they are not entitled to?
Precisely.
However, if a 'hash' of the password is sent in plain text
over HTTP, and all the server knows is the 'hash' of the
password, has the situation really changed?
No. It's the programmer's choice to let the client perform
the encryption in this scenario. Sure, one could send the
password in plaintext too, and let server encrypt it. This
would be a more traditional approach, and, as long as it
uses HTTPS, an equally secure scheme.

<snip>

If we accept that HTTPS is providing a secure tunnel for transmission of
the password information from the client to the server and so eliminating
the risk of interception we have two points where the password
information can be picked up. At the client (which we cannot do much
about in most cases) and at the server. You have suggested that it is not
a good idea for the passwords to be stored in plain text on the server. I
would agree with that; someone seeing the password on the server could
easily go to a client and enter that password and be logged on with the
privileges granted to that password (assuming that they also know the
user name in question). So the value stored on the server is the
post-hash equivalent of the password.

However, if you hash on client prior to transmission and compare what
arrives with the stored hashed version don't you now have the problem
that someone seeing the hashed version on the server can take that and
insert it on the client at the point where the client side hashing
outputs, pump it into our 'safe' HTTPS tunnel and have it recognised when
it comes out of the other end? While if the hashing is done on the
server, and it is the password text that is transmitted, seeing the
post-hash version on the server will not tell someone what password text
they could be inserting on the client, and the only point where they
could insert the post-hash version to gain access is in the code that
does the password verification on the server. And if they can get at (and
influence) that code they don't actually need to know any passwords at
all.

Richard.
yes, that is the problem of a "password equivalent" just using a hash
sent from client and comparing with has on server, so the javascript
routine does a hash of the (password+seed)
where the seed is sent by the server along with the form,
this is actually what gets sent.
the server knows what seed it sent which it stores as a session,
when it receives the hash(password+seed)
it performs the same thing server side and finding the results are the
same means its ok. and immediately expired the seed from the session
so if the traffis /is/ somehow intercepted and played back, the server
no longer knows the seed meaning it cannot perform hash(password+seed)

However you are thinking but how can the server do hash(password+seed)
when it doesnt have the plaintext password in teh database, right! It
can only do hash( db_hash_password+seed) where db_hashed_password is
the prehashed form of the plaintext password that /is/ stored in the
database.

so the javascript client must hash twice first to get the hashed form
of the password, and then adding the seed and hashing that.

hash( hash(password)+seed )
it is /this/ that the server then does.

eliminating the replay attack using the seed, and never needing to
know the plaintext on the server.

Mar 17 '07 #26

This discussion thread is closed

Replies have been disabled for this discussion.