Go library for generating and using One Time Passwords.
Go to file
2016-01-11 08:03:04 +09:00
.gitignore initial commit 2015-11-28 15:26:18 +00:00
common.go Adding otp code and updated README. 2016-01-11 08:03:04 +09:00
hotp_example_test.go Adding otp code and updated README. 2016-01-11 08:03:04 +09:00
hotp_test.go Adding otp code and updated README. 2016-01-11 08:03:04 +09:00
hotp.go Adding otp code and updated README. 2016-01-11 08:03:04 +09:00
LICENSE initial commit 2015-11-28 15:26:18 +00:00
otp_test.go Adding otp code and updated README. 2016-01-11 08:03:04 +09:00
otp.go Adding otp code and updated README. 2016-01-11 08:03:04 +09:00
README.md Adding otp code and updated README. 2016-01-11 08:03:04 +09:00
totp_example_test.go Adding otp code and updated README. 2016-01-11 08:03:04 +09:00
totp_test.go Adding otp code and updated README. 2016-01-11 08:03:04 +09:00
totp.go Adding otp code and updated README. 2016-01-11 08:03:04 +09:00

otp

Go library for generating and using One Time Passwords. Supports both HOTP (RFC4226) and TOTP (RFC6238). Can be used for both server and client roles.

GoDoc

Examples

OTP Server

import (
  "dev.justinjudd.org/justin/otp"
)

var Issuer = "example.com"

func CreateKeyForUser(user string) {

  opts := otp.NewHOTPKeyOptions()
  opts.Issuer = Issuer
  opts.Label = user
  key := otp.NewHOTPKey(opts)

  // Store this string variable in your database
  keyURL := key.URL()

  // Provide the URL to the customer so they can include it in their 2FA client.
  // Can email URL, or present QR code encoding of the URL
}

func CheckUsersCode(user string, code string) (bool, error) {
  // Retrieve this string variable from your database
  var keyURL string

  key, err := otp.FromURL(keyURL)
  if err != nil {
    return false, err
  }

  // Ensure you are using the correct key
  if key.Label != user {
    return false, nil
  }

  success := key.Verify(code)

  // Counter has been updated, update this info in the database
  // Don't need this step for TOTP keys as the counter is time-based
  keyURL = key.URL()


  return success
}

OTP Client

import (
  "dev.justinjudd.org/justin/otp"
)

// Just an example for storing OTP keys on the client
var keys map[Key]string


// Key is used as keys for the otp key storing map
type Key struct {
	Issuer, Label string
}

func GetCode(issuer, username string) (string, error) {

  mapKey := Key{issuer, username}

  // Get the stored Key URL
  keyURL, ok := keys[mapKey]
  if !ok {
    return "", nil
  }

  // Build the key from the URL
  key, err := otp.FromURL(keyURL)
  if err != nil {
    return "", err
  }

  // Verify Issuer and Label are correct
  if key.Issuer != issuer || key.Label != username {
    return "", nil
  }

  code := key.OTP()

  // If using HOTP, than need to save the state
  keyURL = key.URL()
  keys[mapKey]= keyURL

  return code, nil
}