{"id":18605360,"url":"https://github.com/fny/clean_pbkdf2","last_synced_at":"2025-10-09T16:40:55.636Z","repository":{"id":146371361,"uuid":"38949761","full_name":"fny/clean_pbkdf2","owner":"fny","description":"Dead-simple, RFC-compliant PBKDF2 implementation for Ruby","archived":false,"fork":false,"pushed_at":"2015-07-13T18:42:13.000Z","size":132,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-02T03:48:27.572Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fny.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-12T04:17:45.000Z","updated_at":"2018-12-18T00:17:48.000Z","dependencies_parsed_at":"2023-03-31T16:48:48.491Z","dependency_job_id":null,"html_url":"https://github.com/fny/clean_pbkdf2","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fny/clean_pbkdf2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fny%2Fclean_pbkdf2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fny%2Fclean_pbkdf2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fny%2Fclean_pbkdf2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fny%2Fclean_pbkdf2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fny","download_url":"https://codeload.github.com/fny/clean_pbkdf2/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fny%2Fclean_pbkdf2/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001779,"owners_count":26083173,"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","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-11-07T02:21:06.585Z","updated_at":"2025-10-09T16:40:55.596Z","avatar_url":"https://github.com/fny.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Clean PBKDF2 :closed_lock_with_key:\n\n[![Gem Version](https://badge.fury.io/rb/clean_pbkdf2.svg)](http://badge.fury.io/rb/clean_pbkdf2)\n[![Build Status](https://travis-ci.org/fny/clean_pbkdf2.svg?branch=master)](https://travis-ci.org/fny/clean_pbkdf2)\n[![Test Coverage](https://codeclimate.com/github/fny/clean_pbkdf2/badges/coverage.svg)](https://codeclimate.com/github/fny/clean_pbkdf2)\n[![Code Climate](https://codeclimate.com/github/fny/clean_pbkdf2/badges/gpa.svg)](https://codeclimate.com/github/fny/clean_pbkdf2)\n[![Inline docs](http://inch-ci.org/github/fny/clean_pbkdf2.svg?branch=master)](http://inch-ci.org/github/fny/clean_pbkdf2)\n\nA dead-simple, RFC-compliant PBKDF2 implementation using HMAC-AnyOpenSSLDigest as the PRF.\n\n - No monkey patching\n - Simple API\n - [Fast XORs on any platform](https://github.com/fny/xorcist)\n - Works on any rubies that support keyword arguments\n\n## Usage\n\n```ruby\nrequire 'pbkdf2'\n\nPBKDF2.hash_password(\n  password: 'yOurSPecialSecret❤❤❤',\n  salt: 'AtLeast64BitsIsKosher',\n  iterations: 100000,\n  # Default: 'sha256'. Accepts whatever `OpenSSL::Digest` does.\n  hash_function: 'sha256',\n  # Optional. Defaults to the length of the hash_function output.\n  key_length: 32\n) # =\u003e \\xA4\\xBF\\x10\\x91\\x1C,\\xEB}9lD2\\xBAp'T\u003e#m$v\\xAE\\xF0\\x0FX\\xB9\\xCF_\\x82\\x91\\x9C\\xA4\"\n```\n\nUse `PBKDF2.hash_password_hex` for the hexadecimal output.\n\nWant to keep a singleton around can use for hashing passwords?\n\n```ruby\nengine = PBKDF2::Engine.new(\n  iterations: 100000,\n  # Default: 'sha256', accepts whatever `OpenSSL::Digest` does\n  hash_function: 'sha256',\n  # Optional. Defaults to the length of the hash_function output.\n  key_length: 32\n)\nengine.hash_password('yOurSPecialSecret❤❤❤!!!', 'ShakeItLikeASaltShaker')\n# =\u003e \"\\xDB\\x84a\\x12\\xFC\\xC1\\xC2\\x92s\\r\\x97@\\x83\\x95|\\xA0\\x9DZ\\xF9\\xC6\\x80{\\x9Bi\\xA5\\xBD\\x03\\x1D\\xF4m\\x87H\"\n```\n\nUse `PBKDF2::Engine#hash_password_hex` for the hexadecimal output.\n\n### How many iterations should I use?\n\nFrom [\"Recommended # of iterations when using PKBDF2-SHA256?\"](http://security.stackexchange.com/questions/3959/recommended-of-iterations-when-using-pkbdf2-sha256) on the Information Security Stack Exchange:\n\n\u003e You should use the maximum number of rounds which is tolerable, performance-wise, in your application. The number of rounds is a slowdown factor, which you use on the basis that under normal usage conditions, such a slowdown has negligible impact for you (the user will not see it, the extra CPU cost does not imply buying a bigger server, and so on). This heavily depends on the operational context: what machines are involved, how many user authentications per second... so there is no one-size-fits-all response.\n\n[OSWAP's password storage cheat sheet](https://web.archive.org/web/20130115191143/https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet) used to recommend 64,000 iterations as of 2012 doubling every two years (i.e. 90,510 in 2013).\n\n## Standards Compliance\n\nThis implementation conforms to [RFC 2898](https://www.ietf.org/rfc/rfc2898.txt), and has been tested using the test vectors in Appendix B of [RFC 3962](https://www.ietf.org/rfc/rfc3962.txt) and [RFC 6070](https://www.ietf.org/rfc/rfc6070.txt).\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'clean_pbkdf2'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install clean_pbkdf2\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/fny/clean_pbkdf2. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffny%2Fclean_pbkdf2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffny%2Fclean_pbkdf2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffny%2Fclean_pbkdf2/lists"}