{"id":13408928,"url":"https://github.com/jltorresm/otpgo","last_synced_at":"2025-03-14T14:30:22.744Z","repository":{"id":38402529,"uuid":"288737490","full_name":"jltorresm/otpgo","owner":"jltorresm","description":"Time-Based One-Time Password (TOTP) and HMAC-Based One-Time Password (HOTP) library for Go.","archived":false,"fork":false,"pushed_at":"2021-02-27T19:43:16.000Z","size":72,"stargazers_count":68,"open_issues_count":2,"forks_count":9,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-07-31T20:32:16.874Z","etag":null,"topics":["authenticator","authy","google-authenticator","hotp","rfc-4226","rfc-6238","totp","totp-codes"],"latest_commit_sha":null,"homepage":"","language":"Go","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/jltorresm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2020-08-19T13:20:23.000Z","updated_at":"2024-06-24T05:08:24.000Z","dependencies_parsed_at":"2022-08-18T13:21:42.148Z","dependency_job_id":null,"html_url":"https://github.com/jltorresm/otpgo","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jltorresm%2Fotpgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jltorresm%2Fotpgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jltorresm%2Fotpgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jltorresm%2Fotpgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jltorresm","download_url":"https://codeload.github.com/jltorresm/otpgo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243593148,"owners_count":20316140,"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":["authenticator","authy","google-authenticator","hotp","rfc-4226","rfc-6238","totp","totp-codes"],"created_at":"2024-07-30T20:00:56.667Z","updated_at":"2025-03-14T14:30:22.126Z","avatar_url":"https://github.com/jltorresm.png","language":"Go","funding_links":[],"categories":["身份验证和OAuth","Authentication and Authorization","Authentication and OAuth","认证和OAuth授权","Uncategorized"],"sub_categories":["Contents"],"readme":"# otpgo\nHMAC-Based and Time-Based One-Time Password (HOTP and TOTP) library for Go. \nImplements [RFC 4226][rfc4226] and [RFC 6238][rfc6238].\n\n[![Mentioned in Awesome Go][awesomeBadge]][awesomeLink]\n[![License][licenseBadge]][licenseLink]\n[![Go Report Card][goReportBadge]][goReportLink]\n[![Test Status][testStatusBadge]][testStatusLink]\n[![Coverage Status][coverageBadge]][coverageLink]\n[![PkgGoDev][pkgGoDevBadge]][pkgGoDevLink]\n[![Latest Release][releaseBadge]][releaseLink]\n\n# Contents\n- [Supported Operations](#supported-operations)\n- [Reading Material](#reading-material)\n- [Usage](#usage)\n    - [Generating Codes](#generating-codes)\n    - [Verifying Codes](#verifying-codes)\n    - [Registering with Authenticator App](#registering-with-authenticator-apps)\n        - [QR Code](#qr-code)\n        - [Manual Registration](#manual-registration)\n- [Defaults](#defaults)\n    - [HOTP Parameters](#hotp-parameters)\n    - [TOTP Parameters](#totp-parameters)\n\n## Supported Operations\n- Generate HOTP and TOTP codes.\n- Verify HOTP an TOTP codes.\n- Export OTP config as a [Google Authenticator URI][googleURI].\n- Export OTP config as a QR code image (used to register secrets in authenticator apps).\n- Export OTP config as a JSON.\n\n## Reading Material\n- [HOTP: An HMAC-Based One-Time Password Algorithm][rfc4226]\n- [TOTP: Time-Based One-Time Password Algorithm][rfc6238]\n- [Google Authenticator Key URI Format][googleURI]\n- [Browser Authenticator Demo][debugger]\n\n## Usage\n\n### Generating Codes\nThe simplest way to generate codes is to create the HOTP/TOTP struct and call \n`Generate()`\n\n```go\n// \n// HMAC-Based\n//\n\n// Will use all default values, counter starts in 0\nh := otpgo.HOTP{}\ntoken, _ := h.Generate()\n\n// Increment counter and generate next code\nh.Counter++\ntoken2, _ := h.Generate()\n\n//\n// Time-Based\n//\n\n// Will use all default values\nt := otpgo.TOTP{}\ntoken, _ := t.Generate()\n```\n\nEach type allows customization. For **HMAC-Based** tokens you can specify:\n- **Key**: Secret string, base32 encoded\n- **Counter**: Unsigned int\n- **Leeway**: Unsigned int\n- **Algorithm**: One of `HmacSHA1`, `HmacSHA256` or `HmacSHA512`\n- **Length**: `Length1` up to `Length8`\n\nFor **Time-Based** tokens you can specify:\n- **Key**: Secret string, base32 encoded\n- **Period**: Integer, period length in seconds\n- **Delay**: Integer, acceptable number of steps for validation\n- **Algorithm**: One of `HmacSHA1`, `HmacSHA256` or `HmacSHA512`\n- **Length**: `Length1` up to `Length8`\n\n### Verifying Codes\nOnce you receive a token from the user you can verify it by specifying the \nexpected parameters and calling `Validate(token string)`.\n\n```go\n// \n// HMAC-Based\n//\nh := otpgo.HOTP{\n    Key: \"my-secret-key\",\n    Counter: 123, // The expected counter\n}\nok, _ := h.Validate(\"the-token\")\n\n//\n// Time-Based\n//\nt := otpgo.TOTP{\n    Key: \"my-secret-key\",\n}\nok, _ = t.Validate(\"the-token\")\n```\n\nWhen calling `HOTP.Validate()` note that the internal counter will be increased\nif validation is successful, so that the next valid token will correspond to the\nincreased counter.\n\nBoth `HOTP` and `TOTP` will accept tokens that match the exact \n`Counter`/`Timestamp` or a token within the specified `Leeway`/`Delay`.\n\n### Registering With Authenticator Apps\nMost authenticator apps will give the user 2 options to register a new account:\nscan a QR code which contains all config and secrets for the OTP generation, or \nmanually enter the secret key and additional info (such as username and issuer).\nThe former being the preferred way because of the ease of use and the avoidance\nof human error.\n\n#### QR Code\nTo generate the QR code just get the `KeyUri` and call the `QRCode` method:\n```go\notp := otpgo.TOTP{}\nbase64EncodedQRImage, _ := otp.\n   KeyUri(\"john.doe@example.org\", \"A Company\").\n   QRCode()\n\n// Then use base64EncodedQRImage however you like\n// e.g.: send it to the client to display as an image\n```\n\n#### Manual registration\nManual registration usually requires the user to type in the OTP config \nparameters by hand. The KeyUri type can be easily JSON encoded to then send the \nparams to an external caller or any other place.\n```go\notp := otpgo.TOTP{\n    Key: \"YOUR_KEY\",\n    Period: 30,\n    Delay: 1,\n    Algorithm: config.HmacSHA1,\n    Length: 6\n}\nku := otp.KeyUri(\"john.doe@example.org\", \"A Company\")\njsonKeyUri, _ := json.Marshal(ku)\n\n// Then use jsonKeyUri however you like\n// e.g.: send it to the client for further processing\n```\n\n## Defaults\nIf caller doesn't provide a custom configuration when generating OTPs. The \nlibrary will ensure the following default values (any empty value will be \nfilled).\n\n### HOTP Parameters\n|Parameter        |Default Value                      |\n|:---------------:|:---------------------------------:|\n|Leeway           |`1` counter down \u0026 up              |\n|Hash / Algorithm |`SHA1`                             |\n|Length           |`6`                                |\n|Key              |`64` random bytes `base32` encoded |\n\n### TOTP Parameters\n|Parameter        |Default Value                      |\n|:---------------:|:---------------------------------:|\n|Period           |`30` seconds                       |\n|Delay            |`1` period under \u0026 over            |\n|Hash / Algorithm |`SHA1`                             |\n|Length           |`6`                                |\n|Key              |`64` random bytes `base32` encoded |\n\n[licenseBadge]: https://img.shields.io/github/license/jltorresm/otpgo\n[licenseLink]: https://github.com/jltorresm/otpgo/blob/main/LICENSE\n[goReportBadge]: https://goreportcard.com/badge/github.com/jltorresm/otpgo\n[goReportLink]: https://goreportcard.com/report/github.com/jltorresm/otpgo\n[testStatusBadge]: https://img.shields.io/github/workflow/status/jltorresm/otpgo/test?label=test\u0026logo=github\n[testStatusLink]: https://github.com/jltorresm/otpgo/actions?query=workflow%3Atest\n[pkgGoDevBadge]: https://pkg.go.dev/badge/github.com/jltorresm/otpgo\n[pkgGoDevLink]: https://pkg.go.dev/github.com/jltorresm/otpgo\n[releaseBadge]: https://img.shields.io/github/v/release/jltorresm/otpgo?include_prereleases\n[releaseLink]: https://github.com/jltorresm/otpgo/releases/latest\n[coverageBadge]: https://coveralls.io/repos/github/jltorresm/otpgo/badge.svg?branch=main\n[coverageLink]: https://coveralls.io/github/jltorresm/otpgo?branch=main\n[awesomeBadge]: https://awesome.re/mentioned-badge.svg\n[awesomeLink]: https://github.com/avelino/awesome-go\n\n[rfc4226]: https://tools.ietf.org/html/rfc4226\n[rfc6238]: https://tools.ietf.org/html/rfc6238\n[googleURI]: https://github.com/google/google-authenticator/wiki/Key-Uri-Format\n[debugger]: https://rootprojects.org/authenticator/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjltorresm%2Fotpgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjltorresm%2Fotpgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjltorresm%2Fotpgo/lists"}