While developing a Ruby on Rails application using a commonly used authentication library named devise, I noticed from the prefix $2a$ of the produced password hashes in the application database that it's using a bcrypt variant.

I read up about crypt and bcrypt on Wikipedia and noticed that newer variants of bcrypt are supposed to produce a prefix of $2y$ because a non-OpenBSD implementation by someone named Solar Designer had a "major security flaw" in 2011 and therefore it is unclear if the $2a$ hashes were produced by a secure implemenation.

I found out that devise is using a C and Java binding named bcrypt-ruby which indeed bundles a C-implementation copied from John the Ripper which is stated to be written by a Solar Designer. Now I'm wondering if this implementation may still vulnerable to this "major security flaw".

Can anyone bring light to this topic?


The version history of the file at the crypt repository of the John the Ripper project, from which the file seems to have originated, may help answer my question.

2 Answers 2


The code you refer to has been corrected. If you check out the source on Github vs the posted diff fix by Solar Designer, you can see that the sign-extension has been noted and corrected (lines 553 through 556).

Keep in mind that even though prefix $2a$ is not recommended, neither is $2x$ which simply states that the buggy implementation is being used -- albeit, now you know. According to the Wikipedia entry, you want to ensure your hashes are prefixed with $2y$. However, this was not the original fix according to Solar Designer's email noting the problem. That fix merely ensured that to REQUEST the buggy behaviour (for backward compatibility), you would explicitly use version prefix $2x$. The original $2a$ was retained to produce NEW, CORRECT behaviour (see line 609). Therefore, the code in ruby-bcrypt is correct, but you don't explicitly know it as per the recommendations in the Wikipedia article.


As announced on openwall, this bug was related to non-ASCII characters with the 8th bit set:

What's worse, in some cases (but not in all) one, two, or three characters immediately preceding the 8-bit characters were ignored by the password hash computation. Thus, many passwords containing characters with the 8th bit set are significantly easier to crack than it was previously expected.

If you read the README of bcrypt-ruby there is a note which addresses this issue.

Note: JRuby versions of bcrypt-ruby <= 2.1.3 had a security vulnerability that was fixed in >= 2.1.4. If you used a vulnerable version to hash passwords with international characters in them, you will need to re-hash those passwords. This vulernability only affected the JRuby gem.

This is clarified here:

Versions of jBCrypt before 0.3 suffered from a bug related to character encoding that substantially reduced the entropy of hashed passwords containing non US-ASCII characters. An incorrect encoding step transparently replaced such characters by '?' prior to hashing. In the worst case of a password consisting solely of non-US-ASCII characters, this would cause its hash to be equivalent to all other such passwords of the same length.

Thus, since it has been fixed in the jRuby version of the library, i'd guess it's fixed in the MRI version as well.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .