{"id":19974545,"url":"https://github.com/twooster/strap","last_synced_at":"2025-05-04T02:32:51.978Z","repository":{"id":57553621,"uuid":"109491607","full_name":"twooster/strap","owner":"twooster","description":"SRP (Secure Remote Password) 6/6a library for Elixir","archived":false,"fork":false,"pushed_at":"2017-11-05T13:11:39.000Z","size":19,"stargazers_count":12,"open_issues_count":0,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-30T16:56:29.834Z","etag":null,"topics":["authentication-protocol","elixir","srp","srp-6a"],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/twooster.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-04T12:06:26.000Z","updated_at":"2024-08-07T15:54:40.000Z","dependencies_parsed_at":"2022-08-28T10:51:10.679Z","dependency_job_id":null,"html_url":"https://github.com/twooster/strap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twooster%2Fstrap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twooster%2Fstrap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twooster%2Fstrap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twooster%2Fstrap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/twooster","download_url":"https://codeload.github.com/twooster/strap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224379812,"owners_count":17301525,"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":["authentication-protocol","elixir","srp","srp-6a"],"created_at":"2024-11-13T03:15:23.064Z","updated_at":"2024-11-13T03:15:23.803Z","avatar_url":"https://github.com/twooster.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Strap - SRP6/6a (Secure Remote Password) for Elixir\n\nThis is a simple module that helps you implement the Secure Remote Password\n(SRP) protocol in Elixir applications. For more information about SRP, see\nthe [design documents](http://srp.stanford.edu/design.html) and\n[RFC5054](https://tools.ietf.org/html/rfc5054).\n\n[![Build Status](https://travis-ci.org/twooster/strap.svg?branch=master)](https://travis-ci.org/twooster/strap)\n[![Hex.pm Version](http://img.shields.io/hexpm/v/strap.svg?style=flat)](https://hex.pm/packages/strap)\n\n## Installation\n\nThis package can be installed by adding `strap` to your list of dependencies in\n`mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:strap, \"~\u003e 0.1.1\"}\n  ]\nend\n```\n\nIf you're running inside of a Phoenix application, you may need to ensure the\nErlang crypto application is loaded.\n\n```elixir\ndef application do\n  [\n    extra_applications: [\n      :logger,\n      :crypto\n    ]\n  ]\nend\n```\n\n## Documentation\n\nThe HexDocs.pm documentation is available [here](https://hexdocs.pm/strap).\n\n## SRP Flow\n\nA typical SRP request/response flow looks like this:\n\n1. Client gets username/password from user\n\n2. Client -\u003e Server: Client sends the username to the server.\n\n3. Server looks up the user's information, from a database for example.\n   This information would be the prime, generator, salt, and so-called verifier\n   value for this user. Optionally, if the server doesn't know this user, it\n   may return/calculate fake values to obscure the user's lack-of-presence.\n\n4. Server generates a public value, based on the prime, generator, verifier,\n   and an ephemeral randomly-generated private value only it knows.\n\n5. Server -\u003e Client: Server sends the prime, generator, salt, and\n   public value back to the client.\n\n6. Client generates a public value, based on the prime, generator, and\n   an ephemeral randomly-generated private value only it knows.\n\n7. Client -\u003e Server: Client sends its public value to the server.\n\n8. Server generates a pre-shared master key based upon the information it has.\n\n9. Client generates a pre-shared master key based upon the information it has.\n\nThe server and client should, at this point, verify that their pre-shared master\nkeys match. For example, the client could send a `HMAC(key, server-public-key)`\nto the server, and the server could send `HMAC(key, client-public-key)` back\nto the client.\n\nAltenatively, if the preshared key will be utilized for further encrypted\ncommunication, not just authentication, the server and the client can simply\nexchange encrypted messages using an agreed-upon cipher (e.g. AES-256). A\nfailure to decrypt messages indicates a lack of knowledge of the preshared key.\n\n## Usage\n\nThis library helps with steps 4, 6, 8, and 9, above. An example flow might look\nlike:\n\n```elixir\n# Client\n\nusername = get_username()\nprivate_client_password = get_password()\n\n# Server\n\n# Fetch verifier and salt from database\n{salt, private_server_verifier} = get_salt_and_verifier(username)\n# Use \"known-good\" prime/generator; could also be stored in database\n{prime, generator} = Strap.prime_group(2048)\n\nserver =\n  Strap.protocol(:srp6a, prime, generator)\n  |\u003e Strap.server(verifier)\n\nserver_public_value = Strap.public_value(server)\n\n# Client\n\nclient =\n  Strap.protocol(:srp6a, prime, generator)\n  |\u003e Strap.client(username, private_client_password, salt)\n\nclient_public_vlaue = Strap.public_value(client)\n\n# Server\n\n{:ok, private_server_session_key} =\n  Strap.session_key(server, client_public_value)\n\n# Client\n\n{:ok, private_client_session_key} =\n  Strap.session_key(client, server_public_value)\n\n# At this point, the following should be true:\n\n^private_server_session_key = private_client_session_key\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwooster%2Fstrap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftwooster%2Fstrap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwooster%2Fstrap/lists"}