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
SEC Adopts Amendments to Fund Names Rule
Deducting Your Car to Your Business
English Bulldog Puppies For Sale Under 1000 In Florida
Katie Pavlich Bikini Photos
Gamevault Agent
Pieology Nutrition Calculator Mobile
Hocus Pocus Showtimes Near Harkins Theatres Yuma Palms 14
Hendersonville (Tennessee) – Travel guide at Wikivoyage
Compare the Samsung Galaxy S24 - 256GB - Cobalt Violet vs Apple iPhone 16 Pro - 128GB - Desert Titanium | AT&T
Vardis Olive Garden (Georgioupolis, Kreta) ✈️ inkl. Flug buchen
Craigslist Dog Kennels For Sale
Things To Do In Atlanta Tomorrow Night
Non Sequitur
Crossword Nexus Solver
How To Cut Eelgrass Grounded
Pac Man Deviantart
Alexander Funeral Home Gallatin Obituaries
Energy Healing Conference Utah
Geometry Review Quiz 5 Answer Key
Hobby Stores Near Me Now
Icivics The Electoral Process Answer Key
Allybearloves
Bible Gateway passage: Revelation 3 - New Living Translation
Yisd Home Access Center
Home
Shadbase Get Out Of Jail
Gina Wilson Angle Addition Postulate
Celina Powell Lil Meech Video: A Controversial Encounter Shakes Social Media - Video Reddit Trend
Walmart Pharmacy Near Me Open
Marquette Gas Prices
A Christmas Horse - Alison Senxation
Ou Football Brainiacs
Access a Shared Resource | Computing for Arts + Sciences
Vera Bradley Factory Outlet Sunbury Products
Pixel Combat Unblocked
Movies - EPIC Theatres
Cvs Sport Physicals
Mercedes W204 Belt Diagram
Mia Malkova Bio, Net Worth, Age & More - Magzica
'Conan Exiles' 3.0 Guide: How To Unlock Spells And Sorcery
Teenbeautyfitness
Where Can I Cash A Huntington National Bank Check
Topos De Bolos Engraçados
Sand Castle Parents Guide
Gregory (Five Nights at Freddy's)
Grand Valley State University Library Hours
Holzer Athena Portal
Hello – Cornerstone Chapel
Stoughton Commuter Rail Schedule
Nfsd Web Portal
Selly Medaline
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.