You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Rasmus Lerdorf <ra...@lerdorf.on.ca> on 1999/02/01 00:16:26 UTC

Re: basic auth broken

> You have to do it at run time, not compile time.  The normal way of
> switching between crypts on FreeBSD is to change the link for libcrypt to
> the md5 or DES one.  Both binary packages and people who change this
> would be broken by a compile time check.  
> 
> We have to remember that the whole point of this is to make our md5 
> passwords work on any Apache installation on any platform, plus make
> the native ones work on that particular platform.

But, these various crypt() implementations on the different operating
systems all have different capabilities.  You can for example have a
password file with DES, MD5 and Blowfish encrypted passwords all
intermingled and working perfectly on OpenBSD.  On most FreeBSD and Linux
boxes you can have DES and MD5 strings in the same file.

What I was trying to say in my other post (vaguely I guess) is that we
should be using crypt() directly instead of ap_MD5Encode() to generate the
MD5'ed password.  

And I don't think we can have it both ways.  We can't both create passwd
files that are cross-platform and also ensure that they work natively.  If
I have hacked my OpenBSD system to use nothing but BlowFish and I want
Apache to understand my native BlowFish encrypted passwords, then Apache
needs to use my BlowFish crypt() to generate these.  These passwords are
never going to be portable to other systems that do not support BlowFish.

I think the right way to approach this is to have a run-time check using
something like the tests I posted.  They are just a couple of simple
crypt() checks and can easily be done at runtime.  Then we will know which
encryption types are supported by the native crypt() function.  In
addition to this we can provide an Apache-portable mechanism which will
hopefully match one of the native ones so the user gets both, but if it
doesn't the user should get the choice of which one to use.

So, on my OpenBSD box I might see:

./htpasswd -h
Usage: htpasswd [-cdmbp] passwordfile username
(Your system supports DES, MD5 and BlowFish encrypted passwords natively)
   -c   create a new file
   -d   generate DES encrypted passwords (Default)
   -m   generate MD5 encrypted passwords
   -b   generate BlowFish encrypted passwords
   -p   generate portable Apache MD5 passwords (same as -d on this architecture)

Whereas on a normal Solaris box I might see:

./htpasswd -h
Usage: htpasswd [-cdmbp] passwordfile username
(Your system supports DES encrypted passwords natively)
   -c   create a new file
   -d   generate DES encrypted passwords (Default)
   -p   generate portable Apache MD5 passwords

-Rasmus


Re: basic auth broken

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Rasmus Lerdorf wrote:
> 
> What I was trying to say in my other post (vaguely I guess) is that we
> should be using crypt() directly instead of ap_MD5Encode() to generate the
> MD5'ed password.

The whole reason this came up is is that there *is* no
'native crypt()' on Win32.
-- 
#ken	P-)}

Ken Coar                    <http://Web.Golux.Com/coar/>
Apache Group member         <http://www.apache.org/>
"Apache Server for Dummies" <http://Web.Golux.Com/coar/ASFD/>

Re: basic auth broken

Posted by Rasmus Lerdorf <ra...@lerdorf.on.ca>.
> So it sounds as though we should branch off and not try to
> make our portable passwords be recognisable as using the
> same algorithm as anyone else's.  I.e., use our own unique
> significator (and beef up our encyption a bit).  If it happens
> that ours is identical to FreeBSD's, at least we're not
> claiming it's the same as any other MD5 algorithm.
> 
> How about directly copying FreeBSD's, but changing the format
> to '$apr1$<salt>$<hash>'?  That gives some room for
> growth.

I think that would be safe.  And if you use the same length of SALT as the
FreeBSD implementation, if someone really needed to migrate a password
file from one to the other they could simply do a s/apr1/1/
and it should work.

-Rasmus


Re: basic auth broken

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Rasmus Lerdorf wrote:
> 
> Hrm, that could be true.  It wouldn't surprise me if some OS developer out
> there thought it would be a good idea to "enhance" their crypt function
> and either accidentally or by design make it similar but not identical to
> the FreeBSD implementation.

So it sounds as though we should branch off and not try to
make our portable passwords be recognisable as using the
same algorithm as anyone else's.  I.e., use our own unique
significator (and beef up our encyption a bit).  If it happens
that ours is identical to FreeBSD's, at least we're not
claiming it's the same as any other MD5 algorithm.

How about directly copying FreeBSD's, but changing the format
to '$apr1$<salt>$<hash>'?  That gives some room for
growth.
-- 
#ken	P-)}

Ken Coar                    <http://Web.Golux.Com/coar/>
Apache Group member         <http://www.apache.org/>
"Apache Server for Dummies" <http://Web.Golux.Com/coar/ASFD/>

Re: basic auth broken

Posted by Rasmus Lerdorf <ra...@lerdorf.on.ca>.
> As I said earlier, that may be a valid assumption to make.  ie. the use of
> $1$ by FreeBSD has established a standard of sorts.  Perhaps.  The risk we
> run is that if we are ever wrong, then native passwords will not work at
> all on that platform and we have a headache in terms of changing our
> portable format, having to support the old then-legacy $1$ format on other
> platforms, etc. 

Hrm, that could be true.  It wouldn't surprise me if some OS developer out
there thought it would be a good idea to "enhance" their crypt function
and either accidentally or by design make it similar but not identical to
the FreeBSD implementation.

-Rasmus


Re: basic auth broken

Posted by Marc Slemko <ma...@worldgate.com>.
On Sun, 31 Jan 1999, Rodent of Unusual Size wrote:

> Marc Slemko wrote:
> > 
> > This whole issue is about how we can tell, while reading it, if the
> > password we are reading from the htpasswd file is in native or portable
> > format.
> 
> Of the N different platforms that use the '$1$' significator
> to identify MD5 passwords, how many can interoperate?

As I said earlier, that may be a valid assumption to make.  ie. the use of
$1$ by FreeBSD has established a standard of sorts.  Perhaps.  The risk we
run is that if we are ever wrong, then native passwords will not work at
all on that platform and we have a headache in terms of changing our
portable format, having to support the old then-legacy $1$ format on other
platforms, etc. 

> I suspect that it's only our implementation that's out
> of kilter, and adopting the FreeBSD algorithm would
> likely solve thi altogether.  But that's just opinion,
> not founded on fact.

Plus, it wouldn't be a bad idea to adopt something a bit more expensive to
calculate in any case.

> Maybe we should just use '$ap$' and assume there won't
> be any collisions.  If a password doesn't start with
> '$ap$' we regard it as utterly opaque and feed it to
> crypt() instead.


Re: basic auth broken

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Marc Slemko wrote:
> 
> This whole issue is about how we can tell, while reading it, if the
> password we are reading from the htpasswd file is in native or portable
> format.

Of the N different platforms that use the '$1$' significator
to identify MD5 passwords, how many can interoperate?
I suspect that it's only our implementation that's out
of kilter, and adopting the FreeBSD algorithm would
likely solve thi altogether.  But that's just opinion,
not founded on fact.

Maybe we should just use '$ap$' and assume there won't
be any collisions.  If a password doesn't start with
'$ap$' we regard it as utterly opaque and feed it to
crypt() instead.
-- 
#ken	P-)}

Ken Coar                    <http://Web.Golux.Com/coar/>
Apache Group member         <http://www.apache.org/>
"Apache Server for Dummies" <http://Web.Golux.Com/coar/ASFD/>

Re: basic auth broken

Posted by "James H. Cloos Jr." <cl...@jhcloos.com>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

>>>>> "Rasmus" == Rasmus Lerdorf <ra...@lerdorf.on.ca> writes:

Rasmus> BlowFish: 60 chars, $2a$07$ + 9 chars of SALT + encoded string
Rasmus> eg:
Rasmus> $2a$07$rasmuslerO............gl95GkTKn53Of.H4YchXl5PwvvW.5ri

Note that the `07' there corresponds to the ESP_BLOWFISH Encapsulating
Security Payload transform id from rfc2407.  If this is not
coincidental, then these other ESP trans ids are of interest:

rfc2407> Transform ID   Value
rfc2407> ------------   -----
rfc2407> RESERVED       0
rfc2407> ESP_DES_IV64   1
rfc2407> ESP_DES        2
rfc2407> ESP_3DES       3
rfc2407> ESP_RC5        4
rfc2407> ESP_IDEA       5
rfc2407> ESP_CAST       6
rfc2407> ESP_BLOWFISH   7
rfc2407> ESP_3IDEA      8
rfc2407> ESP_DES_IV32   9
rfc2407> ESP_RC4        10
rfc2407> ESP_NULL       11

- -JimC
- -- 
James H. Cloos, Jr.  <http://www.jhcloos.com/cloos/public_key> 1024D/ED7DAEA6 
<cl...@jhcloos.com>     E9E9 F828 61A4 6EA9 0F2B  63E7 997A 9F17 ED7D AEA6
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v0.9.2 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE2tf5qmXqfF+19rqYRAoaUAJ9eRNvK1r9N64B0KnTLKCyxW+pzKwCgoLjD
Hgl8pmFFVP55XUBkr2sz+Uk=
=Mqpq
-----END PGP SIGNATURE-----

Re: basic auth broken

Posted by Rasmus Lerdorf <ra...@lerdorf.on.ca>.
> This whole issue is about how we can tell, while reading it, if the
> password we are reading from the htpasswd file is in native or portable
> format.

Ok, I guess I got lost somewhere along the way then.  I thought that
particular concept was known.  Through experimentation and as per my
earlier post, this is what I have found:

Standard DES: 13 chars, first two chars is the SALT and rest is encoded str
          eg: rl.3StKT.4T8M

Extended DES: 20 chars, first 9 chars is the SALT and rest is encoded str
          eg: _J9..rasmBYk8r9AiWNc

MD5: 34 chars made up of $1$ + 8 chars of SALT + $ + encoded string
          eg: $1$rasmusle$rISCgZzpwk3UhDidwXvin0

BlowFish: 60 chars, $2a$07$ + 9 chars of SALT + encoded string
          eg: $2a$07$rasmuslerO............gl95GkTKn53Of.H4YchXl5PwvvW.5ri

I guess as far as we are concerned we should just make sure that the MD5
encoded string we generate match the MD5 case above.  I have tested that
one on OpenBSD, FreeBSD and Linux.  Those were the only platforms I could
find out of the set I have access to that supported MD5 natively in their
crypt() function.

Currently in htpasswd.c it is generating a 2-char salt for the md5
encoding and the ap_MD5Encode() function only groks a 2-char salt.  Like
you said, yank the MD5Encode() code out of crypt.c on FreeBSD or Linux
(since they seem to be using the same algorithm) and change htpasswd.c to
generate a salt with something like:

        strcpy(salt, "$1$");
        to64(&salt[3], rand(), 4);
        to64(&salt[7], rand(), 4);
        strcpy(&salt[11], "$");

And call this the portable format.  It should correspond to the native
formats on the systems that have an MD5-capable crypt() function.

-Rasmus


Re: basic auth broken

Posted by Marc Slemko <ma...@worldgate.com>.
On Sun, 31 Jan 1999, Rasmus Lerdorf wrote:

> > > And I don't think we can have it both ways.  We can't both create passwd
> > > files that are cross-platform and also ensure that they work natively.  If
> > 
> > That isn't what we care about.  We care about being able to make a passwd
> > file that will work on any platform, _or_ making one that will work on the
> > native platform.  Now, that portable format may be the native format
> > sometimes and vice versa, but that is just a side effect.
> 
> Why don't we care about native compatibility?  I have two sites, for
> example, where the password file I use for Apache is the same password
> file I use for a CVS pserver.  If suddenly Apache starting using some
> "portable" format which did not match the native encryption I was using to
> generate my password file for my CVS system, things would get messy.  I
> would have to get in there and hack one of them.

No, we care about both of them.  We need a portable format.  We also need
the native format.  But we do not need any array of various native
formats, etc.  All we need is a single native format for each platform,
exactly like it is now.  The only thing that is changing is the addition
of an _optional_ portable format, which happens to also be used on
platforms where there is no native format.

This whole issue is about how we can tell, while reading it, if the
password we are reading from the htpasswd file is in native or portable
format.


Re: basic auth broken

Posted by Rasmus Lerdorf <ra...@lerdorf.on.ca>.
> > And I don't think we can have it both ways.  We can't both create passwd
> > files that are cross-platform and also ensure that they work natively.  If
> 
> That isn't what we care about.  We care about being able to make a passwd
> file that will work on any platform, _or_ making one that will work on the
> native platform.  Now, that portable format may be the native format
> sometimes and vice versa, but that is just a side effect.

Why don't we care about native compatibility?  I have two sites, for
example, where the password file I use for Apache is the same password
file I use for a CVS pserver.  If suddenly Apache starting using some
"portable" format which did not match the native encryption I was using to
generate my password file for my CVS system, things would get messy.  I
would have to get in there and hack one of them.

-Rasmus


Re: basic auth broken

Posted by Marc Slemko <ma...@znep.com>.
On Sun, 31 Jan 1999, Rasmus Lerdorf wrote:

> > You have to do it at run time, not compile time.  The normal way of
> > switching between crypts on FreeBSD is to change the link for libcrypt to
> > the md5 or DES one.  Both binary packages and people who change this
> > would be broken by a compile time check.  
> > 
> > We have to remember that the whole point of this is to make our md5 
> > passwords work on any Apache installation on any platform, plus make
> > the native ones work on that particular platform.
> 
> But, these various crypt() implementations on the different operating
> systems all have different capabilities.  You can for example have a
> password file with DES, MD5 and Blowfish encrypted passwords all
> intermingled and working perfectly on OpenBSD.  On most FreeBSD and Linux
> boxes you can have DES and MD5 strings in the same file.

That doesn't matter.  The only thing we need to care about it using the
native crypt() or our md5 passwords.  The reason we need our md5 is for
win32, and it has the nice side effect of letting people generate
portable passwd files if they want.  

It doesn't matter if our md5 matches any other platform or not, but we
need some way to tell if a password is our md5 or native.

> 
> What I was trying to say in my other post (vaguely I guess) is that we
> should be using crypt() directly instead of ap_MD5Encode() to generate the
> MD5'ed password.  

We can't do that.  The whole point is we need a portable format.  I don't
see any need for us to go crazy with a zillion ways, just native and our
md5. 

The only reason for making it compatible with FreeBSD's native md5, is
then we can perhaps make the assumption that "$1$" == do_it_this_way,
because FreeBSD already has the "$1$" id well defined. 

If we don't do that, then we need to make up our own identifier and do all
the stuff necessary to ensure we don't have conflicts, etc.

This is necessary so we can transparently use a passwd file that uses
either the native crypt or our md5 stuff.  As I already mentioned, the
other option is to require that the user specify which format it should
be.

> And I don't think we can have it both ways.  We can't both create passwd
> files that are cross-platform and also ensure that they work natively.  If

That isn't what we care about.  We care about being able to make a passwd
file that will work on any platform, _or_ making one that will work on the
native platform.  Now, that portable format may be the native format
sometimes and vice versa, but that is just a side effect.