README
¶
🔑 cryptography
Application-developer-oriented library with commonly applied cryptographic operations.
Contents
- Overview
- Motivation
- What's in the box
- Getting Started
- Performance
- Examples
- Supported Algorithms
- Tests
- Contributing
- References
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 ].
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)
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.
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)
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 ¶
- func Checksum(message []byte) uint32
- func DecryptAeadGkms(ciphertextHex string, keyName string) (string, error)
- func DecryptAesGcm(ciphertextHex string, key string) (string, error)
- func DecryptChaCha20(ciphertext string, key string) (string, error)
- func DecryptRsa(ciphertextHex string, privateKeyPem string) (string, error)
- func DecryptRsaGkms(ciphertextHex string, privateKeyName string) (string, error)
- func EcdsaKeyPair() (*ecdsa.PrivateKey, *ecdsa.PublicKey, error)
- func EcdsaKeyPairHex() (string, string, error)
- func EcdsaPrivateKeyFromHex(privateKeyHex string) (*ecdsa.PrivateKey, error)
- func EcdsaPublicKeyFromHex(publicKeyHex string) (*ecdsa.PublicKey, error)
- func EncryptAeadGkms(message string, keyName string) (string, error)
- func EncryptAesGcm(message string, key string) (string, error)
- func EncryptChaCha20(message string, key string) (string, error)
- func EncryptRsa(plainText string, puplicKeyPem string) (string, error)
- func EncryptRsaGkms(ciphertextHex string, privateKeyName string) (string, error)
- func EnvelopeDecryptAes(ciphertext string, encryptedSymmetricKey string, privateKeyPem string) (string, error)
- func EnvelopeEncryptAes(message string, publicKeyPem string) (string, string, error)
- func HashPassword(password string, salt string) (string, error)
- func HashPasswordCustom(password string, salt string, time, memory uint32, threads uint8, ...) (string, error)
- func Key128b() (string, error)
- func Key256b() (string, error)
- func Key512b() (string, error)
- func KeyChaCha20() (string, error)
- func PublicKeyPemFromPrivateKeyPem(privateKeyPem string) (string, error)
- func PublicRsaKeyFromPrivateKeyName(privateKeyName string) (*rsa.PublicKey, error)
- func RandomHex(nBytes int) (string, error)
- func RsaKeyPair() (*rsa.PrivateKey, *rsa.PublicKey, error)
- func RsaKeyPairBase64() (string, string, error)
- func RsaKeyPairPem() (string, string, error)
- func RsaPrivateKeyAsPemStr(privatekey *rsa.PrivateKey) string
- func RsaPrivateKeyFromPemStr(privateKeyPEM string) (*rsa.PrivateKey, error)
- func RsaPublicKeyAsPemStr(publicKey *rsa.PublicKey) (string, error)
- func RsaPublicKeyFromPemStr(publicKeyPem string) (*rsa.PublicKey, error)
- func Sha256Digest(text string) string
- func SignEcdsa(message string, privateKeyHex string) (string, error)
- func SignGkms(message string, privateKeyName string) (string, error)
- func SignRsaPKCS1v15(message string, privateKeyPem string) (string, error)
- func SignRsaPss(message string, privateKeyPem string) (string, error)
- func VerifyEcdsa(message string, signatureHex string, publicKeyHex string) error
- func VerifyRsaPKCS1v15(message string, signatureHex string, publicKeyPem string) error
- func VerifyRsaPss(message string, signatureHex string, publicKeyPem string) error
- func VerifySignatureGkms(message string, signatureHex string, publicKeyPem string) error
- type TotpManager
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DecryptAeadGkms ¶
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 ¶
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 ¶
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 ¶
DecryptRsa performs RSA OAEP asymmetric decryption using a key in PEM format. It implements the reverse operation of EncryptRsa
func DecryptRsaGkms ¶
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
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
EcdsaPublicKeyFromHex parses a hex-encoded ECDSA public key into *ecdsa.PublicKey
func EncryptAeadGkms ¶
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 ¶
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 ¶
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 ¶
EncryptRsa performs RSA OAEP public key encryption using a key in PEM format
func EncryptRsaGkms ¶
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
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
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 ¶
Key128b generates a 128-bit key as HEX-string using a random generator fit for cryptographic purposes
func Key256b ¶
Key256b generates a 256-bit key as HEX-string using a random generator fit for cryptographic purposes
func Key512b ¶
Key512b generates a 512-bit key as HEX-string using a random generator fit for cryptographic purposes
func KeyChaCha20 ¶
KeyChaCha20 generates a 256-bit key as HEX-string using a random generator fit for cryptographic purposes
func PublicKeyPemFromPrivateKeyPem ¶
PublicKeyPemFromPrivateKeyPem gets the PEM formated RSA public key from the respective PEM formated private key
func PublicRsaKeyFromPrivateKeyName ¶
PublicRsaKeyFromPrivateKeyName creates an *rsa.Publickey from an GCP KMS RSA private key referenced by [privateKeyName]
func RsaKeyPair ¶
func RsaKeyPair() (*rsa.PrivateKey, *rsa.PublicKey, error)
RsaKeyPair generates a pair of RSA keys
func RsaKeyPairBase64 ¶ added in v1.3.0
RsaKeyPairBase64 RsaKeyPair generates a pair of RSA keys in Base64 format
func RsaKeyPairPem ¶
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 ¶
RsaPublicKeyAsPemStr converts an *rsa.PublicKey into a PEM formatted one
func RsaPublicKeyFromPemStr ¶
RsaPublicKeyFromPemStr converts a PEM formated RSA public key into *rsa.PublicKey
func Sha256Digest ¶
Sha256Digest generates a HEX-encoded message digest from a string input
func SignEcdsa ¶ added in v1.1.0
SignEcdsa issues hex-encoded ECDSA P256 digital signatures using a hex-encoded private key
func SignGkms ¶
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 ¶
SingRsa issues RSA PKCS1v15 digital signatures using a PEM formated private key
func SignRsaPss ¶
SingRsaPss issues RSA PSS digital signatures using a PEM formated private key
func VerifyEcdsa ¶ added in v1.1.0
VerifyEcdsa checks the validity of ECDSA P256 digital signatures using a hex-encoded public key
func VerifyRsaPKCS1v15 ¶
VerifyRsaPKCS1v15 checks the validity of RSA PKCS1v15 digital signatures using a PEM formated public key
func VerifyRsaPss ¶
VerifyRsaPss checks the validity of RSA PSS digital signatures using a PEM formated public key
func VerifySignatureGkms ¶
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