Git Product home page Git Product logo

gotp's Introduction

GOTP - The Golang One-Time Password Library

build-status MIT License

GOTP is a Golang package for generating and verifying one-time passwords. It can be used to implement two-factor (2FA) or multi-factor (MFA) authentication methods in anywhere that requires users to log in.

Open MFA standards are defined in RFC 4226 (HOTP: An HMAC-Based One-Time Password Algorithm) and in RFC 6238 (TOTP: Time-Based One-Time Password Algorithm). GOTP implements server-side support for both of these standards.

GOTP was inspired by PyOTP.

Installation

$ go get github.com/xlzd/gotp

Usage

Check API docs at https://godoc.org/github.com/xlzd/gotp

Time-based OTPs

totp := gotp.NewDefaultTOTP("4S62BZNFXXSZLCRO")
totp.Now()  // current otp '123456'
totp.At(1524486261)  // otp of timestamp 1524486261 '123456'

# OTP verified for a given timestamp
totp.Verify('492039', 1524486261)  // true
totp.Verify('492039', 1520000000)  // false

// generate a provisioning uri
totp.ProvisioningUri("demoAccountName", "issuerName")
// otpauth://totp/issuerName:demoAccountName?secret=4S62BZNFXXSZLCRO&issuer=issuerName

Counter-based OTPs

hotp := gotp.NewDefaultHOTP("4S62BZNFXXSZLCRO")
hotp.At(0)  // '944181'
hotp.At(1)  // '770975'

// OTP verified for a given timestamp
hotp.Verify('944181', 0)  // true
hotp.Verify('944181', 1)  // false

// generate a provisioning uri
hotp.ProvisioningUri("demoAccountName", "issuerName", 1)
// otpauth://hotp/issuerName:demoAccountName?secret=4S62BZNFXXSZLCRO&counter=1&issuer=issuerName

Generate random secret

secretLength := 16
gotp.RandomSecret(secretLength) // LMT4URYNZKEWZRAA

Google Authenticator Compatible

GOTP works with the Google Authenticator iPhone and Android app, as well as other OTP apps like Authy. GOTP includes the ability to generate provisioning URIs for use with the QR Code scanner built into these MFA client apps via otpObj.ProvisioningUri method:

gotp.NewDefaultTOTP("4S62BZNFXXSZLCRO").ProvisioningUri("demoAccountName", "issuerName")
// otpauth://totp/issuerName:demoAccountName?secret=4S62BZNFXXSZLCRO&issuer=issuerName


gotp.NewDefaultHOTP("4S62BZNFXXSZLCRO").ProvisioningUri("demoAccountName", "issuerName", 1)
// otpauth://hotp/issuerName:demoAccountName?secret=4S62BZNFXXSZLCRO&counter=1&issuer=issuerName

This URL can then be rendered as a QR Code which can then be scanned and added to the users list of OTP credentials.

Working example

Scan the following barcode with your phone's OTP app (e.g. Google Authenticator):

Demo

Now run the following and compare the output:

package main

import (
	"fmt"
	"github.com/xlzd/gotp"
)

func main() {
	fmt.Println("Current OTP is", gotp.NewDefaultTOTP("4S62BZNFXXSZLCRO").Now())
}

License

GOTP is licensed under the MIT License

gotp's People

Contributors

dlptr avatar mergenchik avatar pablodz avatar shadiestgoat avatar xlzd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gotp's Issues

'@' Symbol

gotp/utils.go

Line 42 in fab697c

label := url.QueryEscape(accountName)

Hi, I've stumbled on your library and like it! While I was testing I noticed this.
Most accounts are linked to email addresses that obviously include '@' symbol.
Any reason why we are URL Escaping the account?

Problem is when passing the URI to a QR code generator the email is translated to ....%40domain.com

unable to generate OTP with more than 9 digits

Hi, I tried to generate and OTP fo 10 digits (I understand that OTPs of more thatn 6-8 digits are really unusual) but the generateOTP() is capping it to 9 digits.
I think the problem is since line 51 (otp.go) clamps to 31b and 1<<31 < 1e10, this can't be more than 9.
I am ok with 9 being a limit, but that should probably be clearly documented and/or asserted somewhere.
Thanks

gotp.RandomSecret(16) generates a random secret of lenth of 26 instead of 16

randomSecret := gotp.RandomSecret(16)
fmt.Println("Random secret:", randomSecret)
// Convert string to byte slice
byteSlice := []byte(randomSecret)

// Get the length of the byte slice (number of bytes)
byteLength := len(byteSlice)
fmt.Println("size",byteLength)  //26

This gives issue when scanning the generated qrcode of provision uri directly by google authenticator on iPhone

Provide a method for checking if secret is valid to avoid panic checking

Calls time Now() and At() can panic if the secret is invalid, but there's no safe way using this library to check if the secret is valid without handling the panic.

Providing a non-panic method for checking this would be ideal (IsValid() or something which could return the err from byteSecret() instead of panicing).

Most APIs should not panic and should just push errors up the stack instead.

How to set step length for TOTP?

TOTP algorithm has the param of control step length , but I don't found it. Please ...

// Generate the current time OTP and expiration time
func (t *TOTP) NowWithExpiration() (string, int64) {
	interval64 := int64(t.interval)
	timeCodeInt64 := time.Now().Unix() / interval64
	expirationTime := (timeCodeInt64 + 1) * interval64
	return t.generateOTP(int(timeCodeInt64)), expirationTime
}

totp.go times other than now

Good afternoon;

In the totp.go function "At" you've got an 'int' timestamp - presumably a UNIX time integer - being fed into that function.

Seeing as you've already got "time" as a dependency, perhaps it might be better for that to be a "Time" object? This way, users of the library can have the Time functions calculate the various windows and such rather than having to extract the current or future time, do the conversion, and then convert to an int to feed into that function.

I already have to call https://golang.org/pkg/time/#Unix to get that, after all

request help: `NowWithExpiration` changes the `secret`

package main

import (
	"fmt"
	"github.com/xlzd/gotp"
	"strings"
)

func main() {
	secret := gotp.RandomSecret(16)
	totp := gotp.NewDefaultTOTP(secret)

	fmt.Println(totp.NowWithExpiration())
	fmt.Println(totp.OTP)

	url := totp.ProvisioningUri("jw", "jwrookie")
	fmt.Println(url)
}

---------------output---------------
440823 1651462380
{ZOTQH5DBJ5RML7W4D24F2F5HDE====== 6 0xc0000a4018}
otpauth://totp/jwrookie:jw?issuer=jwrookie&secret=ZOTQH5DBJ5RML7W4D24F2F5HDE%3D%3D%3D%3D%3D%3D

---------------expectations---------------
440823 1651462380
{ZOTQH5DBJ5RML7W4D24F2F5HDE 6 0xc0000a4018}
otpauth://totp/jwrookie:jw?issuer=jwrookie&secret=ZOTQH5DBJ5RML7W4D24F2F5HDE

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.