{"id":13484017,"url":"https://github.com/bcrypt-ruby/bcrypt-ruby","last_synced_at":"2025-05-15T14:07:20.525Z","repository":{"id":397217,"uuid":"15293","full_name":"bcrypt-ruby/bcrypt-ruby","owner":"bcrypt-ruby","description":"bcrypt-ruby is a Ruby binding for the OpenBSD bcrypt() password hashing algorithm, allowing you to easily store a secure hash of your users' passwords.","archived":false,"fork":false,"pushed_at":"2024-10-29T23:10:47.000Z","size":385,"stargazers_count":1951,"open_issues_count":18,"forks_count":282,"subscribers_count":49,"default_branch":"master","last_synced_at":"2025-05-15T14:07:08.143Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bcrypt-ruby.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2008-05-07T23:29:27.000Z","updated_at":"2025-05-12T03:22:48.000Z","dependencies_parsed_at":"2024-02-26T00:42:41.526Z","dependency_job_id":"9b19be6e-c832-4bbe-9ba1-9d4b0fa390b3","html_url":"https://github.com/bcrypt-ruby/bcrypt-ruby","commit_stats":{"total_commits":276,"total_committers":61,"mean_commits":4.524590163934426,"dds":0.8514492753623188,"last_synced_commit":"2d235482b5c994bab09caa3fb4ece3e333c537ed"},"previous_names":["codahale/bcrypt-ruby"],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcrypt-ruby%2Fbcrypt-ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcrypt-ruby%2Fbcrypt-ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcrypt-ruby%2Fbcrypt-ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcrypt-ruby%2Fbcrypt-ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bcrypt-ruby","download_url":"https://codeload.github.com/bcrypt-ruby/bcrypt-ruby/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254355335,"owners_count":22057354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T17:01:18.022Z","updated_at":"2025-05-15T14:07:15.515Z","avatar_url":"https://github.com/bcrypt-ruby.png","language":"C","readme":"# bcrypt-ruby\n\nAn easy way to keep your users' passwords secure.\n\n* https://github.com/bcrypt-ruby/bcrypt-ruby/tree/master\n\n[![Github Actions Build Status](https://github.com/bcrypt-ruby/bcrypt-ruby/actions/workflows/ruby.yml/badge.svg?branch=master)](https://github.com/bcrypt-ruby/bcrypt-ruby/actions/workflows/ruby.yml)\n\n## Why you should use `bcrypt()`\n\nIf you store user passwords in the clear, then an attacker who steals a copy of your database has a giant list of emails\nand passwords. Some of your users will only have one password -- for their email account, for their banking account, for\nyour application. A simple hack could escalate into massive identity theft.\n\nIt's your responsibility as a web developer to make your web application secure -- blaming your users for not being\nsecurity experts is not a professional response to risk.\n\n`bcrypt()` allows you to easily harden your application against these kinds of attacks.\n\n*Note*: JRuby versions of the bcrypt gem `\u003c= 2.1.3` had a [security\nvulnerability](https://www.mindrot.org/files/jBCrypt/internat.adv) that\nwas fixed in `\u003e= 2.1.4`. If you used a vulnerable version to hash\npasswords with international characters in them, you will need to\nre-hash those passwords. This vulnerability only affected the JRuby gem.\n\n## How to install bcrypt\n\n    gem install bcrypt\n\nThe bcrypt gem is available on the following Ruby platforms:\n\n* JRuby\n* RubyInstaller builds on Windows with the DevKit\n* Any modern Ruby on a BSD/OS X/Linux system with a compiler\n\n## How to use `bcrypt()` in your Rails application\n\n*Note*: Rails versions \u003e= 3 ship with `ActiveModel::SecurePassword` which uses bcrypt-ruby.\n`has_secure_password` [docs](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password)\nimplements a similar authentication strategy to the code below.\n\n### The _User_ model\n```ruby\nrequire 'bcrypt'\n\nclass User \u003c ActiveRecord::Base\n  # users.password_hash in the database is a :string\n  include BCrypt\n\n  def password\n    @password ||= Password.new(password_hash)\n  end\n\n  def password=(new_password)\n    @password = Password.create(new_password)\n    self.password_hash = @password\n  end\nend\n```\n### Creating an account\n```ruby\ndef create\n  @user = User.new(params[:user])\n  @user.password = params[:password]\n  @user.save!\nend\n```\n### Authenticating a user\n```ruby\ndef login\n  @user = User.find_by_email(params[:email])\n  if @user.password == params[:password]\n    give_token\n  else\n    redirect_to home_url\n  end\nend\n```\n## How to use bcrypt-ruby in general\n```ruby\nrequire 'bcrypt'\n\nmy_password = BCrypt::Password.create(\"my password\")\n#=\u003e \"$2a$12$K0ByB.6YI2/OYrB4fQOYLe6Tv0datUVf6VZ/2Jzwm879BW5K1cHey\"\n\nmy_password.version              #=\u003e \"2a\"\nmy_password.cost                 #=\u003e 12\nmy_password == \"my password\"     #=\u003e true\nmy_password == \"not my password\" #=\u003e false\n\nmy_password = BCrypt::Password.new(\"$2a$12$K0ByB.6YI2/OYrB4fQOYLe6Tv0datUVf6VZ/2Jzwm879BW5K1cHey\")\nmy_password == \"my password\"     #=\u003e true\nmy_password == \"not my password\" #=\u003e false\n```\nCheck the rdocs for more details -- BCrypt, BCrypt::Password.\n\n## How `bcrypt()` works\n\n`bcrypt()` is a hashing algorithm designed by Niels Provos and David Mazières of the OpenBSD Project.\n\n### Background\n\nHash algorithms take a chunk of data (e.g., your user's password) and create a \"digital fingerprint,\" or hash, of it.\nBecause this process is not reversible, there's no way to go from the hash back to the password.\n\nIn other words:\n\n    hash(p) #=\u003e \u003cunique gibberish\u003e\n\nYou can store the hash and check it against a hash made of a potentially valid password:\n\n    \u003cunique gibberish\u003e =? hash(just_entered_password)\n\n### Rainbow Tables\n\nBut even this has weaknesses -- attackers can just run lists of possible passwords through the same algorithm, store the\nresults in a big database, and then look up the passwords by their hash:\n\n    PrecomputedPassword.find_by_hash(\u003cunique gibberish\u003e).password #=\u003e \"secret1\"\n\n### Salts\n\nThe solution to this is to add a small chunk of random data -- called a salt -- to the password before it's hashed:\n\n    hash(salt + p) #=\u003e \u003creally unique gibberish\u003e\n\nThe salt is then stored along with the hash in the database, and used to check potentially valid passwords:\n\n    \u003creally unique gibberish\u003e =? hash(salt + just_entered_password)\n\nbcrypt-ruby automatically handles the storage and generation of these salts for you.\n\nAdding a salt means that an attacker has to have a gigantic database for each unique salt -- for a salt made of 4\nletters, that's 456,976 different databases. Pretty much no one has that much storage space, so attackers try a\ndifferent, slower method -- throw a list of potential passwords at each individual password:\n\n    hash(salt + \"aadvark\") =? \u003creally unique gibberish\u003e\n    hash(salt + \"abacus\")  =? \u003creally unique gibberish\u003e\n    etc.\n\nThis is much slower than the big database approach, but most hash algorithms are pretty quick -- and therein lies the\nproblem. Hash algorithms aren't usually designed to be slow, they're designed to turn gigabytes of data into secure\nfingerprints as quickly as possible. `bcrypt()`, though, is designed to be computationally expensive:\n\n    Ten thousand iterations:\n                 user     system      total        real\n    md5      0.070000   0.000000   0.070000 (  0.070415)\n    bcrypt  22.230000   0.080000  22.310000 ( 22.493822)\n\nIf an attacker was using Ruby to check each password, they could check ~140,000 passwords a second with MD5 but only\n~450 passwords a second with `bcrypt()`.\n\n### Cost Factors\n\nIn addition, `bcrypt()` allows you to increase the amount of work required to hash a password as computers get faster. Old\npasswords will still work fine, but new passwords can keep up with the times.\n\nThe default cost factor used by bcrypt-ruby is 12, which is fine for session-based authentication. If you are using a\nstateless authentication architecture (e.g., HTTP Basic Auth), you will want to lower the cost factor to reduce your\nserver load and keep your request times down. This will lower the security provided you, but there are few alternatives.\n\nTo change the default cost factor used by bcrypt-ruby, use `BCrypt::Engine.cost = new_value`:\n```ruby\nBCrypt::Password.create('secret').cost\n  #=\u003e 12, the default provided by bcrypt-ruby\n\n# set a new default cost\nBCrypt::Engine.cost = 8\nBCrypt::Password.create('secret').cost\n  #=\u003e 8\n```\nThe default cost can be overridden as needed by passing an options hash with a different cost:\n\n    BCrypt::Password.create('secret', :cost =\u003e 6).cost  #=\u003e 6\n\n## More Information\n\n`bcrypt()` is currently used as the default password storage hash in OpenBSD, widely regarded as the most secure operating\nsystem available.\n\nFor a more technical explanation of the algorithm and its design criteria, please read Niels Provos and David Mazières'\nUsenix99 paper:\nhttps://www.usenix.org/events/usenix99/provos.html\n\nIf you'd like more down-to-earth advice regarding cryptography, I suggest reading \u003ci\u003ePractical Cryptography\u003c/i\u003e by Niels\nFerguson and Bruce Schneier:\nhttps://www.schneier.com/book-practical.html\n\n# Etc\n\n* Author  :: Coda Hale \u003ccoda.hale@gmail.com\u003e\n* Website :: https://codahale.com\n","funding_links":[],"categories":["Encryption","C"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcrypt-ruby%2Fbcrypt-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbcrypt-ruby%2Fbcrypt-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcrypt-ruby%2Fbcrypt-ruby/lists"}