Encoding passwords
Hey everyone,
Is there a function out there for pg which allows you to generate a random
number given a seed value? I'm trying to create a users table which would
require the storage of a password in a database field, and I'm hesitant to
put it in there in plain text, despite the fact I plan to put very tight
restrictions on that particular table. Ideally, I would encode each letter
one by one, using the random number generator with the previous letter as a
seed for the next. I was told that certain unixes use a similar way to
store their passwords, and it seemed to make sense for this application. I
noticed that there is a rand() function, but I'm a little slow today and
couldn't think a way to use that in this scenario. Any suggestions would be
greatly appreciated.
Thanks
Mike
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp
On Tue, Sep 25, 2001 at 08:42:04AM -0400,
Mike Arace <mikearace@hotmail.com> wrote:
Is there a function out there for pg which allows you to generate a random
number given a seed value? I'm trying to create a users table which would
require the storage of a password in a database field, and I'm hesitant to
put it in there in plain text, despite the fact I plan to put very tight
restrictions on that particular table. Ideally, I would encode each letter
one by one, using the random number generator with the previous letter as a
seed for the next. I was told that certain unixes use a similar way to
store their passwords, and it seemed to make sense for this application. I
noticed that there is a rand() function, but I'm a little slow today and
couldn't think a way to use that in this scenario. Any suggestions would be
greatly appreciated.
The more normal way to do this is to store a cryptographic hash of the
password in the database and have the application calculate the hash
and compare that to the hash in the database. This approach won't work
if the database is used to store passwords for use by applications in
connecting to other services.
Typical cryptographic hash functions are SHA-1 and MD5 and you shouldn't
have much trouble finding libraries that provide these functions.
On Tue, Sep 25, 2001 at 08:42:04AM -0400, Mike Arace wrote:
Is there a function out there for pg which allows you to generate a random
number given a seed value? I'm trying to create a users table which would
require the storage of a password in a database field, and I'm hesitant to
put it in there in plain text, despite the fact I plan to put very tight
restrictions on that particular table. Ideally, I would encode each letter
one by one, using the random number generator with the previous letter as a
seed for the next. I was told that certain unixes use a similar way to
store their passwords, and it seemed to make sense for this application. I
noticed that there is a rand() function, but I'm a little slow today and
couldn't think a way to use that in this scenario. Any suggestions would begreatly appreciated.
Look into contrib/pgcrypto in CVS, or
http://www.l-t.ee/marko/pgsql/pgcrypto-0.3.tar.gz
in meantime. Gives you crypt() function not unlike in UNIXes.
Also gen_salt() for generating salts for it.
--
marko
Is there a function out there for pg which allows you to generate
a random
number given a seed value? I'm trying to create a users table
which would
There is the following:
"select setseed(<new seed value>);"
This sets the seed for the random() function.
However, the approach we use is more like the suggestion from Bruno Wolf
that you received earlier- In our case we use JDBC to pass data between our
application & the database, so we use the java crypt package to encrypt
everything we get before it gets stored or compared to a stored value & then
just compare the hash. I think his suggestion is the best way *if* your
development environment supports something similar.
-Nick
---------------------------------------------------------------------
Nick Fankhauser
Business:
nickf@doxpop.com Phone 1.765.965.7363 Fax 1.765.962.9788
doxpop - Court records at your fingertips - http://www.doxpop.com/
Personal:
nick@fankhausers.com http://www.fankhausers.com
I personally use encoded password= hash( concat(salt,password)), and store
both the salt and the encoded password. Where hash = sha1 or md5.
The DB columns are: salt, encoded password, encoding method.
Note that apparently there are some cryptographic weaknesses with
concatenating the salt and the password with the salt in the front, the way
I did it unfortunately :). If I recall correctly, if the salt is short then
attackers only need to attack a subset of the full hash. The salt being a
known plaintext. So some say to concat with the salt at the back. I suspect
a long salt should make the attack far less feasible, or alternatively
XORed the salt with the password or maybe hash multiple times.
Unfortunately I can't seem to find the original article.
I haven't got around to changing my apps. It's not too bad since the fields
allow for different encoding methods - for this reason I suggest you have a
field to store the encoding method too.
So you can have 'NONE' or 'SHA1' or 'MD5' or 'SHA1B' and so on.
That said if hostile people get to the stage where they can read the
encoded passwords, you're probably screwed anyway - they're likely to be
able to do other things some even more undesirable. So it's not really a
big deal compared to other issues.
Cheerio,
Link.
At 08:42 AM 9/25/01 -0400, Mike Arace wrote:
Show quoted text
Hey everyone,
Is there a function out there for pg which allows you to generate a random
number given a seed value? I'm trying to create a users table which would
require the storage of a password in a database field, and I'm hesitant to
put it in there in plain text, despite the fact I plan to put very tight
restrictions on that particular table. Ideally, I would encode each letter
one by one, using the random number generator with the previous letter
I personally use encoded password= hash( concat(salt,password)), and store
both the salt and the encoded password. Where hash = sha1 or md5.The DB columns are: salt, encoded password, encoding method.
Note that apparently there are some cryptographic weaknesses with
concatenating the salt and the password with the salt in the front, the way
I did it unfortunately :). If I recall correctly, if the salt is short then
attackers only need to attack a subset of the full hash. The salt being a
known plaintext. So some say to concat with the salt at the back. I suspect
a long salt should make the attack far less feasible, or alternatively
XORed the salt with the password or maybe hash multiple times.
Unfortunately I can't seem to find the original article.I haven't got around to changing my apps. It's not too bad since the fields
allow for different encoding methods - for this reason I suggest you have a
field to store the encoding method too.So you can have 'NONE' or 'SHA1' or 'MD5' or 'SHA1B' and so on.
That said if hostile people get to the stage where they can read the
encoded passwords, you're probably screwed anyway - they're likely to be
able to do other things some even more undesirable. So it's not really a
big deal compared to other issues.
We have new code in 7.2 that will do MD5 encryption of passwords stored
in pg_shadow. We add the salt to the front of the password before
passing through MD5. You are suggesting putting the salt at the end.
I guess the issue is that if you can get the salt part found out, you
can use that to attack the password part. Also, consider that we use
the username as the salt as stored in pg_shadow. We can easily put the
salt in the back, but then there is the risk that a long password would
not take into account the salt. My feeling that this is more a
theoretical concern and we may be opening ourselves up to more problems
if we make the change.
Other ideas?
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
That said if hostile people get to the stage where they can read the
encoded passwords, you're probably screwed anyway - they're likely to be
able to do other things some even more undesirable. So it's not really a
big deal compared to other issues.We have new code in 7.2 that will do MD5 encryption of passwords stored
in pg_shadow. We add the salt to the front of the password before
passing through MD5. You are suggesting putting the salt at the end.I guess the issue is that if you can get the salt part found out, you
can use that to attack the password part. Also, consider that we use
the username as the salt as stored in pg_shadow. We can easily put the
salt in the back, but then there is the risk that a long password would
not take into account the salt. My feeling that this is more a
theoretical concern and we may be opening ourselves up to more problems
if we make the change.
OK, I have applied the following patch to the MD5 code that puts the
salt at the end. We can't change the crypt() stuff because that is
being used in older releases.
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Attachments:
/bjm/difftext/plainDownload+30-22
On Thu, Sep 27, 2001 at 02:58:37PM -0400, Bruce Momjian wrote:
I personally use encoded password= hash( concat(salt,password)), and store
both the salt and the encoded password. Where hash = sha1 or md5.The DB columns are: salt, encoded password, encoding method.
We have new code in 7.2 that will do MD5 encryption of passwords stored
in pg_shadow. We add the salt to the front of the password before
passing through MD5. You are suggesting putting the salt at the end.I guess the issue is that if you can get the salt part found out, you
can use that to attack the password part. Also, consider that we use
the username as the salt as stored in pg_shadow. We can easily put the
salt in the back, but then there is the risk that a long password would
not take into account the salt. My feeling that this is more a
theoretical concern and we may be opening ourselves up to more problems
if we make the change.Other ideas?
It does not matter. As you are using only one round of MD5/SHA1
which are quite fast, on very short data, it is very easy to
brute-force it anyway, salt or no salt. Only good solution for
storing short data hashed is to use very slow algorithm, like
crypt-md5 and crypt-blowfish are doing. On crypt-blowfish
you can even 'tune' the slowness by giving number of rounds
to run.
Another idea is stop storing hashes altogether and use protocol
like SRP which stores on server side on 'verificators'. I am
interested hacking PostgreSQL to use SRP, but have not had time
for it yet.
--
marko
At 07:15 PM 9/27/01 -0400, Bruce Momjian wrote:
I guess the issue is that if you can get the salt part found out, you
can use that to attack the password part. Also, consider that we use
the username as the salt as stored in pg_shadow. We can easily put the
salt in the back, but then there is the risk that a long password would
not take into account the salt. My feeling that this is more a
theoretical concern and we may be opening ourselves up to more problems
if we make the change.OK, I have applied the following patch to the MD5 code that puts the
salt at the end. We can't change the crypt() stuff because that is
being used in older releases.
I think it needs further confirmation, because what I said was from memory
- I still can't find the source- so take what I said with a pinch of erm
MSG. I'd personally go with the XOR rather than concat. And I'd use a
random salt rather than a predictable salt.
But I emphasize again that I believe this is actually a small issue, and
that leaving the salt in front won't really weaken things much looking at
the big picture. Because nowadays computers are so fast and cheap, cracking
the passwords usually boils down to whether the password is weak or not,
and usually the passwords picked are weak, a week at most to crack :). You
use salts just to _discourage_ attackers from precomputing. A skilled and
determined attacker who knows how to exploit any hash-salt weakness will
find it easier to crack the whole blooming computer open and get root.
Cheerio,
Link.
OK, I have applied the following patch to the MD5 code that puts the
salt at the end. We can't change the crypt() stuff because that is
being used in older releases.I think it needs further confirmation, because what I said was from memory
- I still can't find the source- so take what I said with a pinch of erm
MSG. I'd personally go with the XOR rather than concat. And I'd use a
random salt rather than a predictable salt.But I emphasize again that I believe this is actually a small issue, and
that leaving the salt in front won't really weaken things much looking at
the big picture. Because nowadays computers are so fast and cheap, cracking
the passwords usually boils down to whether the password is weak or not,
and usually the passwords picked are weak, a week at most to crack :). You
use salts just to _discourage_ attackers from precomputing. A skilled and
determined attacker who knows how to exploit any hash-salt weakness will
find it easier to crack the whole blooming computer open and get root.
It was easy to throw the salt on the end, and XOR is easy too. Can
somone else comment on this?
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Lincoln Yeoh <lyeoh@pop.jaring.my> writes:
I think it needs further confirmation, because what I said was from memory
- I still can't find the source- so take what I said with a pinch of erm
MSG. I'd personally go with the XOR rather than concat.
Why? AFAIK, appending a salt is a well-understood process with MD5.
I see no reason to think that XORing would be better, and it might be
worse.
And I'd use a random salt rather than a predictable salt.
We do, at least for passwords flowing across the net. There's no
randomness in the salt for a password stored in pg_shadow, but the only
way to have randomness there would be to add a separate column showing
what the random salt was --- so an attacker with access to pg_shadow
would know what the salt was, anyway.
But I emphasize again that I believe this is actually a small issue,
Indeed, but I'd rather get it right now than realize we made a small
error after it's too late to change.
regards, tom lane
Marko Kreen <marko@l-t.ee> writes:
Another idea is stop storing hashes altogether
You can already avoid passwords by using kerberos authentication.
--
Trond Eivind Glomsr�d
Red Hat, Inc.
Another idea is stop storing hashes altogether
You can already avoid passwords by using kerberos authentication.
Are there any good docs on kerberos with postgres? Unlike almost
everything else in this project, I've found them quite lacking. My
biggest question would be I've got kerberos setup and working well. How
do I get postgres to authorize a user.
For the sake of example, let's say I've got the principle:
johndoe@REALM.COM. Do I need to create a principle
johndoe/postgres@REALM.COM? If so, what is the keytab that I'd create
for the postmaster? postgres/host.example.com@REALM.COM?
Thanks. -sc
--
Sean Chittenden
Another idea is stop storing hashes altogether
You can already avoid passwords by using kerberos authentication.
Are there any good docs on kerberos with postgres? Unlike almost
everything else in this project, I've found them quite lacking. My
biggest question would be I've got kerberos setup and working well. How
do I get postgres to authorize a user.
For the sake of example, let's say I've got the principle:
johndoe@REALM.COM. Do I need to create a principle
johndoe/postgres@REALM.COM? If so, what is the keytab that I'd create
for the postmaster? postgres/host.example.com@REALM.COM?
Thanks. -sc
--
Sean Chittenden
sean-pgsql-general@chittenden.org writes:
Are there any good docs on kerberos with postgres?
No. Since you seem to know more about Kerberos than most of us
(ie, more than zero), could we trouble you to dig into it and
write some docs?
You might find there are some bugs to fix too. I doubt that code
has seen much use lately :-(
regards, tom lane
Tom Lane <tgl@sss.pgh.pa.us> writes:
sean-pgsql-general@chittenden.org writes:
Are there any good docs on kerberos with postgres?
No. Since you seem to know more about Kerberos than most of us
(ie, more than zero), could we trouble you to dig into it and
write some docs?You might find there are some bugs to fix too. I doubt that code
has seen much use lately :-(
We've been using it a little lately, and it seems to work (we added a
postgres principle, but that was about it) - one think which would be
nice, though, is multiple authentication methods for the same
database, keyed by user. While you might want to use kerberos for
standard users, you might like to give an unprivileged one access to
some simple selects, to give one example.
--
Trond Eivind Glomsr�d
Red Hat, Inc.
On Sat, Sep 29, 2001 at 07:05:19PM -0700, Sean Chittenden wrote:
For the sake of example, let's say I've got the principle:
johndoe@REALM.COM. Do I need to create a principle
johndoe/postgres@REALM.COM? If so, what is the keytab that I'd create
for the postmaster? postgres/host.example.com@REALM.COM?
You're right about the keytab -- the postmaster needs a key for
"postgres/hostname@REALM" in the keytab file (which it needs to be able
to read -- I often forget that) in order to use Kerberos for
authentication.
Authorization is still handled the same way it would be if you were
using password authentication (i.e., you need to grant privileges to
particular users for particular databases and tables, in your example,
for a user named "johndoe").
HTH,
Nalin