Issue #14915 has been updated by jeremyevans0 (Jeremy Evans).


jeremyevans0 (Jeremy Evans) wrote:
> .htpasswd is an Apache-specific format, and Apache currently supports only 5 password formats: bcrypt, MD5, SHA1, crypt, plain text (https://httpd.apache.org/docs/2.4/misc/password_encryptions.html).  Only bcrypt and MD5 are considered secure.  The MD5 format uses a Apache-specific algorithm with 1000 iterations of MD5, and I'm not aware of a ruby implementation of it.  I believe the bcrypt format is a standard bcrypt except that it uses `2y` instead of `2a` or `2b` as the version, but I have not tested this yet.  I will test it and assuming the bcrypt format is compatible, that is probably the format we should recommend.

Apache htpasswd generates passwords using `$2y$`, but the hashes are the same as `$2a$` format, and Apache handles `$2a$` format just fine.  The bcrypt gem does not consider `$2y$` to match, but will work correctly if `$2y$` is changed to `$2a$`.   According to Wikipedia (https://en.wikipedia.org/wiki/Bcrypt#Versioning_history), `$2y$` instead of `$2a$` was just to note that the hash was not generated by a bad version of the crypt_blowfish PHP library, otherwise the formats are identical.

So to check the passwords in ruby, you would just need to do: `BCrypt::Password.new(password_hash.sub(/\A\$2y$/, '$2a$')) == submitted_password`

Tested using Apache 2.4.33 with the following .htaccess file:

~~~
AuthType Basic
AuthName "Restricted Files"
AuthUserFile "/var/www/passwd"
Require user foo bar
~~~

Where `/var/www/passwd` was populated:

~~~
cd /var/www
touch passwd
htpasswd -bB passwd foo foofoofoo
ruby -r bcrypt -e 'puts BCrypt::Password.create("barbarbar")' > passwd
~~~

Testing that both foo and bar can login with the passwords, and that the ruby bcrypt library can correctly check password hashes generated by htpasswd if you do the `$2y$` to `$2a$` conversion as shown above.

Should I prepare a patch to Webrick to accept :create_password_hash and :check_password_hash options, and add documentation with an example using bcrypt?

----------------------------------------
Feature #14915: Deprecate String#crypt, move implementation to string/crypt
https://bugs.ruby-lang.org/issues/14915#change-73106

* Author: jeremyevans0 (Jeremy Evans)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
This method is system and implementation dependent, and the
portable usage mentioned in the documentation is not truly
portable (doesn't work on OpenBSD) and insecure as it uses DES.
For systems that lack a crypt(3) implementation, Ruby will
happily substitute a version that only supports DES.  It's 2018,
using DES should be avoided if at all possible.

The only internal usage of String#crypt in Ruby is in Webrick,
where it uses DES for basic authentication with an htpasswd file.
That could and should be changed to use a more secure hash by
default (bcrypt since that's the most secure htpasswd format),
or at least allow the user to customize Webrick's authentication.
I expect there are few if any users actively using Webrick's
htpasswd support.

This moves the String#crypt implementation to the string/crypt
extension, but leaves the String#crypt core method.  The core
method prints a deprecation warning, then loads the string/crypt
extension. The string/crypt extension undefines the String#crypt
core method, then defines the previous implementation.

Because extensions use extconf.rb instead of configure for their
configuration, this ports the related configure.ac code to
extconf.rb.  I'm not sure that is done correctly and works on
all platforms, it will need testing.

For systems that lack a crypt(3) implementation, this modifies the
fallback code to only define crypt_r, since that is the only
function that String#crypt will call in that case.

While the patch just deprecates String#crypt, I think
we should plan to remove support from ruby:

2.6: core method deprecated
2.7: core method removed, string/crypt extension ships with ruby
2.8: string/crypt extension moves to external gem, not shipped

---Files--------------------------------
0001-Deprecate-String-crypt-move-implementation-to-string.patch (20.5 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>