cryptography

package module
v1.4.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 1, 2024 License: Apache-2.0 Imports: 28 Imported by: 1

README

🔑 cryptography

GoDoc Go Report Card
Application-developer-oriented library with commonly applied cryptographic operations.

Contents


Overview

A compilation of reliable lower level implementations wrapped as developer-friendly higher level API that is safe, has everything in one place and is easy to use.

Motivation

In our experience with enterprise software we have repeatedly encountered a gap between the developers' need to apply cryptographic operations and the supply of safe and in the meantime easy to use cryptoraphic recipes. Yes, all of it is out there, but getting the entire picture together can take weeks, months or years depending on one's inidividual experience. We went through this journey and now would like to share our work. We intend to continue using this library for our present and future proprietary projects.

What's in the box

We have tried to cover a meaningful variety of cryptographic algorithms which are presently considered industry standard. There are functions for symmetric encryption, asymmetric encryption, digital signatures, time based one time passwords, parallelization resistant hashing and multiple utilities for management of cryptographic keys. One can find both Go native constructs based on the standard crypto library as well as cloud-specific implementations that offer excellent security and key management features. We intend to keep updating the library with additional algorithms and welcome recommendations or feature requests.

Getting started

Installation:

go get github.com/schmuio/cryptography

Import it in your code and and you are ready to go:

package yourpackage

import (
    "github.com/schmuio/cryptography"
)
yourKey, err := cryptography.Key256b()
if err != nil {
    // error handling logic
}
ciphertext, err := cryptography.EncryptAesGcm("some-important-plaintext", yourKey)

Performance

We have prioritised developer convenience and ability to inspect inputs and outputs visually so most functions are designed to consume string inputs and to provide string outputs. This means that every now and then there are a few type conversions that in a be-as-fast-as-possible scenario can be avoided. This does not mean the functions are not fast, on the contrary - this overhead has a infinitesimal impact compared to the computational cost of the underlying cryptographic operation. Unless you plan to apply these functions in loops with a very high number of iterations or are in a the-fastest-takes-it-all situation, the performance is more than fine. In other words, if you need to measure performance in microseconds or hundreds of nanoseconds - you are fine. If a few nanoseconds per operation are an issue - we recommend that you go for lower level implementations.

Examples

For the sake of avoiding repetition we assume that in every example snippet one has already imported the module via adding the following to their code:

package yourpackage

import (
    "github.com/schmuio/cryptography"
)
Example 1 - Symmetric Encryption

Symmetric encryption algorithms use the same key to encrypt the plaintext and decrypt the respective ciphertext. The library offers the two most widely used algorithms for authenticated symmetric encryption - AES-GCM and ChaCha20-Poly1305 [ 1 ].

Example AES-GCM

Create a key:

yourKey, err := cryptography.Key256b()  // Note: alternatively Key128b() can be used

Encrypt:

ciphertext, err := cryptography.EncryptAesGcm("some-important-plaintext", yourKey)

Decrypt:

plaintext, err := cryptography.DecryptAesGcm(ciphertext, yourKey)
Example ChaCha20-Poly1305

Create a key:

yourKey, err := cryptography.KeyChaCha20()

Encrypt:

ciphertext, err := cryptography.EncryptChaCha20("some-important-plaintext", yourKey)

Decrypt:

plaintext, err := cryptography.DecryptChaCha20(ciphertext, yourKey)

⚠ Both algoritms use nonces (numbers-only-used-once) during encryption and reuse of such nonces can have catastrophic consequences (see [ 1 ] for details). In brief, do not use one key for more than 2^32 encryption operations, i.e. rotate the key as frequently as needed so this threshold is not exceeded (see [ 7 ] for an excellent explanation of the problem).

Example 2 - Asymmetric Encryption

Asymmetric encryption algorithms use one key (referred to as 'public key') to encrypt data and another one (referred to as 'private key') to decrypt them. This is particularly useful in scenarios where many parties should be able to encrypt certain information but there is only one party that is to be allowed to decrypt it. Make sure the private key is always stored securely and do not share it. You can share the public key freely and do not need to treat it as a secret. The library implements the ubiquitous RSA-OAEP algorithm for asymmetric encryption/decryption.

Create a key:

privateKey, publicKey, err := cryptography.RsaKeyPairPem()

Encrypt:

ciphertext, err := cryptography.EncryptRsa("some-important-plaintext", publicKey)

Decrypt:

plaintext, err := cryptography.DecryptRsa(ciphertext, privateKey)

⚠ RSA encryption is not designed to encrypt large messages and the maximim size of the plaintext is restricted by the size of the public key (e.g. 2048 bits) including deductions for padding, etc., details can be found in [ 5 ]. If you need to encrypt longer messages and still rely on an asymmetric encryption workflow a solution is to use hybrid encryption - use a symmetric algorithm for the data and encrypt the symmetric key with an asymmetric algorithm.

Example 3 - Digital signatures

Digital signatures are asymmetric cryptography entities that provide proof of the origin of a message and its integrity (i.e. that it comes from the expected source and that it has not been modified). Digital signatures are issued with the private key and are verified with the public key. The private key should be stored securely at all times and should never be shared. The puplic key can be shared with any party that is interested in checking messages signed by the issuer who holds the private key.

Example RSA PSS

Create a key:

privateKey, publicKey, err := cryptography.RsaKeyPairPem()

Sign:

signature, err := cryptography.SignRsaPss("some-very-important-message", privateKeyPem)

Veryfy signature

err = cryptography.VerifyRsaPss("some-very-important-message", signature, publicKeyPem)
Example ECDSA P256
privateKey, publicKey, err := cryptography.EcdsaKeyPairHex()

Sign:

signature, err := cryptography.SignEcdsa("some-very-important-message", privateKey)

Veryfy signature

err = cryptography.VerifyEcdsa("some-very-important-message", signature, publicKey)

⚠ It is recomended that RSA-PSS or ECDSA is used whenever possible whereas RSA-PKCS1v15 is also included for cases where compatibility mandades the use of the latter. See [ 1 ] for a detailed review and comparison of digital signatures algorithms.

Example 4 - Time based one-time passwords

TOTPs are a highly popular method for adding extra security, e.g. in multi-factor authentication settings. They are derived from the present Unix time and a shared secret provided to an HMAC algorithm. The synchronisation of the Unix time clocks of the client and the server, as well as their shared secret, combined with a deterministic hash algorithm enusure that both parties can derive the same code independently, see details here RFC6238. The library provides a straightforward-to-use API for creating TOTPs and secrets rendered as QR codes so that one can very easily integrate it with 2FA apps like Authy, Google Authenticator, Microsoft Authenticator, etc.

Initial step: create a TotpManager instance with all the necessary data:

 secret, err := cryptography.Key512b() // Note: the secret must be of 64-byte size
 if err != nil {
    // error handling logic
 }

 tm := cryptography.TotpManager{
		Issuer:      "yourOrganization",
		AccountName: "yourUserEmail@yourOrganization.com",
		Algorithm:   "SHA1",         // Or SHA256, SHA512
		Period:      30,             // The default period is 30s
		Secret:      []byte(secret), // Use different secret per every client
	}

Generate a TOTP:

totp, err := tm.TOTP()  // The result is a string of 6 decimal digits like "123456"
if err != nil {
    // error handling logic
}

Validate a TOTP:

isValid, err := tm.Validate(totp)
if err != nil {
    // error handling logic
}

Generate QR code:

qrCodeBase64, err := tm.QrCode()
if err != nil {
    // error handling logic
}

// Render this QR code (bs64 encoded image) on your UI to allow the user to onboard for 2-factor authentication with an app like Authy, Google Authenticatior, etc.

⚠ TOTPs standardised with RFC6238 use SHA1 as an HMAC algorithm and the latter is still in seemingly wide use in TOTP contexts. At the time of writing (Decemeber, 2022) Authy, Google Authenticator and Microsoft Authenticator still default to SHA1 and when TOTPs created with SHA256 or SHA512 are passed the latter apps still expect the SHA1-based value. On the other hand others like IBM Verify and Sophos Authenticator seem to already be supporting SHA256-based TOTPs.

The problem is that for long time SHA1 has been proven to be fundamentally insecure and is no longer recommended by NIST [ 2 ], and evidence has been growing it is even more flawed with respect to collision resistance than previously thought [ 3 ], [ 4 ]. However, reportedly it has been "relatively safe" in other contexts [ 4 ]. For example, in TOTP generation collision resitance is not a required property as well as only a small 6-digit part of the whole hash is used so that the generic collision attacks do not seem to be particularlly applicable.

For our purposes we prefer to use SHA256, however we do not argue that the SHA1 cannot be safely used in such a context.

Supported Algorithms

  • AES-GCM >> symmetric encryption >> native*

  • AES-GCM >> symmetric encryption >> via Google Cloud Platform

  • ChaCha20-Poly1305 >> symmetric encryption >> native

  • RSA-OAEP >> asymmetric encryption >> native

  • RSA-OAEP >> asymmetric encryption >> via Google Cloud Platform

  • RSA-PKCS1v15 >> digital signatures >> native

  • RSA-PKCS1v15 >> digital signatures >> via Google Cloud Platform

  • RSA-PSS >> digital signatures >> native

  • RSA-PSS >> digital signatures >> via Google Cloud Platform

  • ECDSA p256 >> digital signatures >> native

  • ECDSA p256/p384/secp256k1 >> digital signatures >> via Google Cloud Platform

  • RFC 6238 >> time-based one-time passwords >> native

  • Argon2 >> ASIC resistant key derivation and hashing >> native

*native refers to as locally executable code which does not rely on any external infrastructure

Tests

Best effort has been made the code to be covered with meaningful tests. In order the Google Cloud Platform KMS-based encryption tests (and functions) to work, one needs to create keys as described in the GCP documentation - for symmetric encrypt/decrypt, asymmetric encrypt/decrypt and asymmetric sign/verify purposes and set their resource names to the environment variables:

  • TEST_GKMS_SYMMETRIC_ENCRYPTION_KEY_RESOURCE_NAME
  • TEST_GKMS_RSA_ENCRYPTION_PRIVATE_KEY_RESOURCE_NAME
  • TEST_GKMS_RSA_SIGN_PRIVATE_KEY_RESOURCE_NAME
  • TEST_GKMS_RSA_SIGN_PUBLIC_KEY_PEM.
    If you intend to use only the native encryption functions please set DISABLE_GCP_TESTS to "1".

Contributing

At present we plan to maintain this library on our own because it is getting shaped by the needs of the projects we are and will be applying it for. As time is particularly limited, we prefer to not manage this repo as a particularly dynamic one. Nevertheless, we would warmly welcome any remarks, recommendations, feature requests or contribution proposals which we'll review on an individual basis. We commit to fix any bugs and inconsistencies in due course. Please contact us on schmu.io@proton.me on any matter of interest.

References

[1] Wong, D.(2021).Real-World Cryptography.Manning Publications

[2] Aumasson, J.P.(2017).Serious Cryptography.No Starch Press

[3] https://duo.com/decipher/sha-1-fully-and-practically-broken-by-new-collision

[4] https://eprint.iacr.org/2020/014.pdf

[5] https://mbed-tls.readthedocs.io/en/latest/kb/cryptography/rsa-encryption-maximum-data-size/)

[6] https://csrc.nist.gov/glossary/term/nonce

[7] https://soatok.blog/2020/12/24/cryptographic-wear-out-for-symmetric-encryption/

[8] https://www.ietf.org/rfc/rfc6238.txt

Documentation

Overview

cryptography provides functions implementing commonly needed cryptographic operations - symmetric encryption, digital signatures, hashes, time based one time passwords. It presents a compact and ready-to-go cryptographic toolbox for developers.

The package is intended to step on trustworthy cryptographic implementations from the Go standard library and the Google Cloud KMS API offering easy to use and intendedly safe cryptographic utilities for a broad set of development cases.

Note of caution: please do not try to change the internal workings of the functions unless you do know what you are doing. If there is a security concern or a recommendation it would be warmly welcomed and promtly addressed.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Checksum

func Checksum(message []byte) uint32

Checksum calculates a crc32 digest of a message

func DecryptAeadGkms

func DecryptAeadGkms(ciphertextHex string, keyName string) (string, error)

DecryptAeadGkms decrypts ciphertexts from EncryptAeadGkms with a particular keyName key (specified by keyName), using the Google KMS service (https://cloud.google.com/kms/docs/encrypt-decrypt). keyName: format "projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/my-key".

The function uses Google's recommended way of operating with the GCP KMS encryption/decryption service and its inclusion here is intended to provide convenience to the developer from having multiple cryptographic tools in one place.

Using this function has a main advantage that the key value is never exposed and is handled securely by the GCP KMS service. The downside is that it binds you to a particular cloud provider as well as it has a minor but still non-zero cost per key and per an encryption/decryption operation.

func DecryptAesGcm

func DecryptAesGcm(ciphertextHex string, key string) (string, error)

DecryptAesGcm peforms AES GCM decryption with an explicitly provided encryption/decryption key (as opposed to a pointer/reference to a key). It reverses the result of EncryptAesGcm.

Note: the result of EncryptAesGcm is a string containing hexadecimal digits so that DecryptAesGcm expects a hex encoded input

func DecryptChaCha20

func DecryptChaCha20(ciphertext string, key string) (string, error)

DecryptChaCha20 performs ChaCha20-poly1305 decryption with an explicitly provided encryption/decryption key (as opposed to a pointer/reference to a key) It reverses the result from EncryptChaCha20

func DecryptRsa

func DecryptRsa(ciphertextHex string, privateKeyPem string) (string, error)

DecryptRsa performs RSA OAEP asymmetric decryption using a key in PEM format. It implements the reverse operation of EncryptRsa

func DecryptRsaGkms

func DecryptRsaGkms(ciphertextHex string, privateKeyName string) (string, error)

DecryptRsaGkms performs RSA OAEP decryption with the Google Cloud Platform's KMS service (https://cloud.google.com/kms/docs/encrypt-decrypt-rsa). privateKeyName: format "projects/my-project/locations/europe/keyRings/my-keyring/cryptoKeys/my-key-name/cryptoKeyVersions/1".

The function uses Google's recommended way of operating with the GCP KMS encryption service and its inclusion here is intended to provide convenience to the developer from having multiple cryptographic tools in one place.

func EcdsaKeyPair added in v1.1.0

func EcdsaKeyPair() (*ecdsa.PrivateKey, *ecdsa.PublicKey, error)

EcdsaKeyPair generates privateKey and public key for ECDSA sign/verify purposes

func EcdsaKeyPairHex added in v1.1.0

func EcdsaKeyPairHex() (string, string, error)

EcdsaKeyPairHex generates hex-encoded privateKey and public key for ECDSA sign/verify purposes

func EcdsaPrivateKeyFromHex added in v1.1.0

func EcdsaPrivateKeyFromHex(privateKeyHex string) (*ecdsa.PrivateKey, error)

EcdsaPrivateKeyFromHex parses a hex-encoded ECDSA private key into *ecdsa.PrivateKey

func EcdsaPublicKeyFromHex added in v1.1.0

func EcdsaPublicKeyFromHex(publicKeyHex string) (*ecdsa.PublicKey, error)

EcdsaPublicKeyFromHex parses a hex-encoded ECDSA public key into *ecdsa.PublicKey

func EncryptAeadGkms

func EncryptAeadGkms(message string, keyName string) (string, error)

EncryptAeadGkms encrypts (AEAD) specified plaintext message with a particular keyName key (specified by keyName), using the Google KMS service (https://cloud.google.com/kms/docs/encrypt-decrypt). keyName: format "projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/my-key".

The function uses Google's recommended way of operating with the GCP KMS encryption service and its inclusion here is intended to provide convenience to the developer from having multiple cryptographic tools in one place.

Using this function has a main advantage that the key value is never exposed and is handled securely by the GCP KMS service. The downside is that it binds you to a particular cloud provider as well as it has a minor but still non-zero cost per key and per an encryption/decryption operation.

func EncryptAesGcm

func EncryptAesGcm(message string, key string) (string, error)

EncryptAesGcm peforms AES GCM encryption with an explicitly provided encryption/decryption key (as opposed to a pointer/reference to a key) The function expects string-type plaintext and key

Note: Do not use this function more than 2^32 with the same key due to the risk of repetition and its potentially very serious security implications (see https://tsapps.nist.gov/publication/get_pdf.cfm?pub_id=51288#page=29), rotate the keys accordingly considering the frequency of encryption operations

func EncryptChaCha20

func EncryptChaCha20(message string, key string) (string, error)

EncryptyChaCha20 performs ChaCha20-poly1305 encryption with an explicitly provided encryption/decryption key (as opposed to a pointer/reference to a key) This is an authenticated encryption algorithm that is an alternative to AES GCM (for details see Wong, D., 2001, "Real-World Cryptography")

func EncryptRsa

func EncryptRsa(plainText string, puplicKeyPem string) (string, error)

EncryptRsa performs RSA OAEP public key encryption using a key in PEM format

func EncryptRsaGkms

func EncryptRsaGkms(ciphertextHex string, privateKeyName string) (string, error)

EncryptRsaGkms performs RSA OAEP encryption with the Google Cloud Platform's KMS service (https://cloud.google.com/kms/docs/encrypt-decrypt-rsa). privateKeyName: format "projects/my-project/locations/europe/keyRings/my-keyring/cryptoKeys/my-key-name/cryptoKeyVersions/1".

The function uses Google's recommended way of operating with the GCP KMS encryption service and its inclusion here is intended to provide convenience to the developer from having multiple cryptographic tools in one place.

Notes: - The private key is requested as a parameter because the function will derive the public key from the private one on the fly. Alternatively, you can store the public key (e.g. as an environment variable) and use DecryptRsa instead. This would add an extra variable to manage but would spare an extra call to the GKMS API on each encryption case. - Using this function has a main advantage that the private key value is never exposed and is handled securely by the GCP KMS service. The downside is that it binds you to a particular cloud provider as well as it has a minor but still non-zero cost per key and per an encryption/decryption operation.

func EnvelopeDecryptAes added in v1.2.0

func EnvelopeDecryptAes(ciphertext string, encryptedSymmetricKey string, privateKeyPem string) (string, error)

EnvelopeDecryptAes performs decryption of ciphertext generated by EnvelopeEncryptAes Note: encryptedSymmetricKey has to be decryptable using privateKeyPem

Note: Asymmetric key is in PEM format

func EnvelopeEncryptAes added in v1.2.0

func EnvelopeEncryptAes(message string, publicKeyPem string) (string, string, error)

EnvelopeEncryptAes performs envelope encryption with one-off symmetric key using AES-GCM as symmetric encryption algorithm and RSA-OAEP as asymmetric one

Note: Asymmetric key is in PEM format

func HashPassword added in v1.4.0

func HashPassword(password string, salt string) (string, error)

HashPassword creates a password hash using the Argon2id algorithm (https://www.password-hashing.net/argon2-specs.pdf), generating an output resistant to dictionary and brute-force attacks specific to MD5 and SHA-X hashing algorithms, please check [https://cryptobook.nakov.com/mac-and-key-derivation/password-encryption] for details.

Parameters are selected using 11th Gen Intel® Core™ i9-11900H @ 2.50GHz × 16 / 32 RAM - performance will vary depending on the host system executing the function.

(!) IMPORTANT: Never use vanilla SHA-X or MD5 hashing algorithms for saving passwords because if the risks related to those algorithms, namely using rainbow tables or brute-forcing based on GPUs, FPGAs or ASICs that allow efficient computation of a sheer amount of hashes at high speed.

func HashPasswordCustom added in v1.4.0

func HashPasswordCustom(password string, salt string, time, memory uint32, threads uint8, keyLen uint32) (string, error)

HashPasswordCustom allows arbitrary tuning of the parameters of the underlying argon2 algorithm

func Key128b

func Key128b() (string, error)

Key128b generates a 128-bit key as HEX-string using a random generator fit for cryptographic purposes

func Key256b

func Key256b() (string, error)

Key256b generates a 256-bit key as HEX-string using a random generator fit for cryptographic purposes

func Key512b

func Key512b() (string, error)

Key512b generates a 512-bit key as HEX-string using a random generator fit for cryptographic purposes

func KeyChaCha20

func KeyChaCha20() (string, error)

KeyChaCha20 generates a 256-bit key as HEX-string using a random generator fit for cryptographic purposes

func PublicKeyPemFromPrivateKeyPem

func PublicKeyPemFromPrivateKeyPem(privateKeyPem string) (string, error)

PublicKeyPemFromPrivateKeyPem gets the PEM formated RSA public key from the respective PEM formated private key

func PublicRsaKeyFromPrivateKeyName

func PublicRsaKeyFromPrivateKeyName(privateKeyName string) (*rsa.PublicKey, error)

PublicRsaKeyFromPrivateKeyName creates an *rsa.Publickey from an GCP KMS RSA private key referenced by [privateKeyName]

func RandomHex

func RandomHex(nBytes int) (string, error)

RandomHex generates a random string with hexadecimal digits

func RsaKeyPair

func RsaKeyPair() (*rsa.PrivateKey, *rsa.PublicKey, error)

RsaKeyPair generates a pair of RSA keys

func RsaKeyPairBase64 added in v1.3.0

func RsaKeyPairBase64() (string, string, error)

RsaKeyPairBase64 RsaKeyPair generates a pair of RSA keys in Base64 format

func RsaKeyPairPem

func RsaKeyPairPem() (string, string, error)

RsaKeyPair generates a pair of RSA keys in PEM format

func RsaPrivateKeyAsPemStr

func RsaPrivateKeyAsPemStr(privatekey *rsa.PrivateKey) string

RsaPrivateKeyAsPemStr converts an *rsa.PrivateKey into PEM formatted one

func RsaPrivateKeyFromPemStr

func RsaPrivateKeyFromPemStr(privateKeyPEM string) (*rsa.PrivateKey, error)

RsaPrivateKeyFromPemStr converts a PEM formated RSA private key into an *rsa.PrivateKey

func RsaPublicKeyAsPemStr

func RsaPublicKeyAsPemStr(publicKey *rsa.PublicKey) (string, error)

RsaPublicKeyAsPemStr converts an *rsa.PublicKey into a PEM formatted one

func RsaPublicKeyFromPemStr

func RsaPublicKeyFromPemStr(publicKeyPem string) (*rsa.PublicKey, error)

RsaPublicKeyFromPemStr converts a PEM formated RSA public key into *rsa.PublicKey

func Sha256Digest

func Sha256Digest(text string) string

Sha256Digest generates a HEX-encoded message digest from a string input

func SignEcdsa added in v1.1.0

func SignEcdsa(message string, privateKeyHex string) (string, error)

SignEcdsa issues hex-encoded ECDSA P256 digital signatures using a hex-encoded private key

func SignGkms

func SignGkms(message string, privateKeyName string) (string, error)

SignGkms issues a hex encoded digitgal signature using the GKMS API.

Supported algorithms are RSA-PSS, RSA PKCS and ECDSA, see details on https://cloud.google.com/kms/docs/algorithms. Which algorithm is used is dictated by the type of the key used for the singing operation.

func SignRsaPKCS1v15

func SignRsaPKCS1v15(message string, privateKeyPem string) (string, error)

SingRsa issues RSA PKCS1v15 digital signatures using a PEM formated private key

func SignRsaPss

func SignRsaPss(message string, privateKeyPem string) (string, error)

SingRsaPss issues RSA PSS digital signatures using a PEM formated private key

func VerifyEcdsa added in v1.1.0

func VerifyEcdsa(message string, signatureHex string, publicKeyHex string) error

VerifyEcdsa checks the validity of ECDSA P256 digital signatures using a hex-encoded public key

func VerifyRsaPKCS1v15

func VerifyRsaPKCS1v15(message string, signatureHex string, publicKeyPem string) error

VerifyRsaPKCS1v15 checks the validity of RSA PKCS1v15 digital signatures using a PEM formated public key

func VerifyRsaPss

func VerifyRsaPss(message string, signatureHex string, publicKeyPem string) error

VerifyRsaPss checks the validity of RSA PSS digital signatures using a PEM formated public key

func VerifySignatureGkms

func VerifySignatureGkms(message string, signatureHex string, publicKeyPem string) error

VerifySignatureGkms checks the validity of a digital signature using the GKMS API

Supported algorithms are RSA-PSS, RSA PKCS and ECDSA, see details on https://cloud.google.com/kms/docs/algorithms. Which algorithm is used is dictated by the type of the key used for the signing operation.

Types

type TotpManager

type TotpManager struct {
	Issuer      string
	AccountName string
	Algorithm   string
	Period      uint
	Secret      []byte // Note: use a different secret for every client/user
}

TotpManager is a an entity encapsulating all necessary data and methods to support the lifecycle of TOTPs (RFC 6238).

Supported hash algorithms are SHA256, SHA512 as well as SHA1. See caveats about SHA1 at https://crypto.stackexchange.com/questions/26510/why-is-hmac-sha1-still-considered-secure and at https://eprint.iacr.org/2006/187.pdf, etc. but please note that RFC 6238 "[...] is based on the HMAC-SHA-1 algorithm (as specified in [RFC2104])" as well as many apps like Microsoft Authenticatior, Google Authenticator and Authy still work only with SHA1, arguably because the collision vulnerabilities of SHA1 are barely exploitable in TOTP generation context where only a small portion of the hash string is used and the rest is truncated.

The public methods necessary to perform the generation and validation actions are attached to this class

func (TotpManager) Key

func (tm TotpManager) Key() (*otp.Key, error)

Key creates a github.com/pquerna/otp *Key object which is subsequently used for creation and validation TOTPs

func (TotpManager) QrCode

func (tm TotpManager) QrCode() (string, error)

QrCode generates a base64 encoded QR code from a particular TotpManager instance

func (TotpManager) TOTP

func (tm TotpManager) TOTP() (string, error)

TOTP creates a 6-digit time based one time password using on the configuration data of a TotpManager instance

func (TotpManager) Validate

func (tm TotpManager) Validate(totpPasscode string) (bool, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL