Go library for generating and using One Time Passwords.
Go to file
2016-01-11 10:03:40 +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_client_example_test.go Updating some of the examples. 2016-01-11 09:56:15 +09:00
hotp_example_test.go Updating some of the examples. 2016-01-11 09:56:15 +09:00
hotp_server_example_test.go Updating some of the examples. 2016-01-11 09:56:15 +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 language hint for markdown examples. 2016-01-11 10:03:40 +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)

  keyURL := key.URL()
  Store(user, keyURL)

  // 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
}

// Store this string variable in your database
func Store(user, url string) {

}

// Retrieve the url string variable from your database
func GetURL(user string) string {
  return ""
}

func CheckUsersCode(user string, code string) (bool, error) {
  keyURL := GetURL(user)

  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, nil
    }

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
}