More Secure Passwords in Bcrypt — Beating the 72 Bytes Limitation | Monterail (2024)

Table of Contents

  1. What's the Problem with Bcrypt's Security?
  2. So How to Beat the 72 Bytes Limitation?
  3. Summary

Storing passwords is a pretty common workflow that needs to be done when developing web applications, so it's best to use well-established solutions for that.

In Rails, it would be devise which under the hood uses bcrypt for password hashing. And this is a great choice as bcrypt is a secure at least at the time of writing algorithm, and is used very commonly in other technologies. For example, Phoenix on Unix system uses it by default, and I saw it often used in NodeJS projects.

More Secure Passwords in Bcrypt — Beating the 72 Bytes Limitation | Monterail (1)

But it has its limitations, and in this post, I will present you one 72 bytes password length limit. I'll also tell you how to solve this.

What's the Problem with Bcrypt's Security?

So, as mentioned above, most implementations of bcrypt are limited to 72 bytes password length. At first glance, this does not seem so bad after all, 72 bytes makes for quite a long password. But let's check what will happen if we provide a bit longer password to Ruby implementation of bcrypt.

irb(main)> password = "a" * 72 + "someextra"
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasomeextra"
irb(main)> hash = BCrypt::Password.create(password)
=> "$2a$12$ijB8LuN33Y6.NoMl3gTLieyd9hYzp7SWD4H6immKiy80DNCTXYgQ."
irb(main)> BCrypt::Password.new(hash) == password
=> true

So our password created what looks like a valid hash, and it is even validated as one. So everything is good, right? Not really. Because if we try to compare that hash to just 72 "a", without the "someextra" part it will still validate:

irb(main)> hash
=> "$2a$12$ijB8LuN33Y6.NoMl3gTLieyd9hYzp7SWD4H6immKiy80DNCTXYgQ."
irb(main)> BCrypt::Password.new(hash) == "a" * 72
=> true

Ok, but as we said before: even without that "someextra" part, as long as the first 72 bytes still create a secure password, it should be fine. But with that, we assume that users create secure passwords, which may not be the case. And if we are using pepper in our setup, a long password can drop it from the hash, reducing its security:

irb(main)> password = "a" * 72 + pepper
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapepper"
irb(main)> hash = BCrypt::Password.create(password)
=> "$2a$12$kMR90psu4jhtp2xb7B35d.36lDuyewZsPEeDRXiVdlrWr9B7CQMVi"
irb(main)> BCrypt::Password.new(hash) == "a" * 72
=> true

What's more, it is important to point out that the limit is 72 bytes, not 72 characters. On the web, we are mostly using UTF-8 (for passwords as well). That means not all characters are 1 byte in size, and one character can take between 1 to 4 bytes.Quick example? Monterail is a Polish company, and in Poland, we have a couple of extra letters, like "ą", which in UTF-8 takes 2 bytes:

irb(main)> "ą".bytesize
=> 2

This means that if we would use only "ą" to create a password, its effective length is reduced to 36 characters:

irb(main)> password = "ą" * 36 + "extra"
=> "ąąąąąąąąąąąąąąąąąąąąąąąąąąąąąąąąąąąąextra"
irb(main)> hash = BCrypt::Password.create(password)
=> "$2a$12$3QyhYPBdqknleoFPiDHn5edo.OF4jgU4D0dYOa/MDncm5EDy0QUB."
irb(main)> BCrypt::Password.new(hash) == "ą" * 36
=> true

To be realistic, in the case of the Polish language, those letters are just something extra on top of the standard Latin alphabet, so in cases of most passwords even if letters like "ą" are used, the effective password length will not be cut in half. But there are alphabets that do not use Latin characters at all and all of them will take more than 1 byte. In extreme cases, the length will be only 24 or maybe even 18 characters, for 3 and 4 bytes accordingly.

And the actual problem here is that it is done silently, no error returned — users don't know that this shortening is happening, even though as shown above, it may silently drop pepper as well.

So How to Beat the 72 Bytes Limitation?

To be fair: this does not make bcrypt insecure — it is a widely used and secure algorithm. It just has a limitation that needs to be taken into consideration when working with it.

There is a great article about password storage on OWASP Cheat Sheet Series, an awesome place to learn more about the problem. And we will use two recommendations from there as solutions to our problem.

One will be to change the algorithm from bcrypt to argon2id, as the password length limit there is 4 GiB, which means: virtually unlimited. So it's important to create some reasonable input limit here, to prevent maliciously long passwords from being provided to create denial attacks.

If argon2 is not an option and you need to stay with bcrypt, the best solution would be to add length validation, to check if a password is not longer than 72 bytes (or even shorter if pepper is used).

Summary

So there you go. The takeaway is this: bcrypt is a secure algorithm but remember that it caps passwords at 72 bytes. You can either check if the passwords are the proper size, or opt to switch to argon2, where you'll have to set a password size limit.

Happy hashing!

More Secure Passwords in Bcrypt — Beating the 72 Bytes Limitation | Monterail (2)

More Secure Passwords in Bcrypt — Beating the 72 Bytes Limitation | Monterail (3)

Rafał Rothenberger

Tags

TechnologyRuby/RailsDevelopment
More Secure Passwords in Bcrypt — Beating the 72 Bytes Limitation | Monterail (2024)
Top Articles
A Minimalist’s Approach to Christmas Dinner - Nourishing Minimalism
How to redeem points using the Bank of America Premium Rewards credit card - The Points Guy
Google Alerts Login
Chokenigg*s
Charleston Rubrankings
Florence Alabama Police
Vlb Aurora
Stanley Steemer Medford Oregon
25X11X10 Atv Tires Tractor Supply
Duelies Sports Bar And Grill Photos
Nudify Review: Is It the Best AI Clothes Remover?
Netronline Historic Aerials
Ups Cc Center
How To Use Google Flights To Find Cheap Prices
91 East Freeway Accident Today 2022
Dover Nh Power Outage
truckoo | Gebrauchte LKW mit einem Klick kaufen | Truckoo
Jimmy John's Order Delivery
1998 Pontiac Firebird Trans Am for sale - Denver, CO - craigslist
Magellan Outdoors Men's Luther Ii Boots
Twitter co-founder Jack Dorsey steps down as chief executive
Emory Vein Clinic
Bangor Daily Sports
Donated Food Value Per Pound 2022
Nikon in 2022: What happened, why, and where next for the Big N?
Roll Out Gutter Extensions Lowe's
Readyset Ochsner.org
Different distance with GPS/Ultratrack - Instinct - Outdoor Recreation Archive
Talx Paperless Pay Shell
Food Universe Near Me Circular
Isabella Lauren Leak
Virement et prélèvement de la DRFIP : qu'est ce que c'est?
Nbstsa Verification
Sofi Stadium Section 512
Sam's Club Reynoldsburg Gas Price
Kallmekris Rape
Grams to Tablespoons Calculator - (g to tbsp Converter)
Why Is My Lookah Dragon Egg Blinking Yellow
Wkbt News 8000
Guadalajara Taqueria Cisco Menu
Tvlistings.com
Miniature Australian Shepherd Craigslist
Musas Tijuana
10 Most Popular Pokémon From the Original 151, Ranked
Spanking Art By Barb
Google Jobs Denver
European Wax Center Toms River Reviews
Warlock Solasta
Vintage Stock Edmond Ok
Qvc Host Dies Lisa Robertson Cause Of Death
Stretch limos were the ultimate status symbol. Now they're going for cheap on Craigslist.
Latest Posts
Article information

Author: Msgr. Refugio Daniel

Last Updated:

Views: 5938

Rating: 4.3 / 5 (54 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Msgr. Refugio Daniel

Birthday: 1999-09-15

Address: 8416 Beatty Center, Derekfort, VA 72092-0500

Phone: +6838967160603

Job: Mining Executive

Hobby: Woodworking, Knitting, Fishing, Coffee roasting, Kayaking, Horseback riding, Kite flying

Introduction: My name is Msgr. Refugio Daniel, I am a fine, precious, encouraging, calm, glamorous, vivacious, friendly person who loves writing and wants to share my knowledge and understanding with you.