50 lines
1.9 KiB
Go
50 lines
1.9 KiB
Go
|
// cryptopasta - basic cryptography examples
|
||
|
//
|
||
|
// Written in 2015 by George Tankersley <george.tankersley@gmail.com>
|
||
|
//
|
||
|
// To the extent possible under law, the author(s) have dedicated all copyright
|
||
|
// and related and neighboring rights to this software to the public domain
|
||
|
// worldwide. This software is distributed without any warranty.
|
||
|
//
|
||
|
// You should have received a copy of the CC0 Public Domain Dedication along
|
||
|
// with this software. If not, see // <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||
|
|
||
|
// Provides a recommended hashing algorithm.
|
||
|
//
|
||
|
// The hash function is HMAC-SHA512/256 where SHA512/256 is as described in
|
||
|
// FIPS 180-4. This construction avoids length-extension attacks while
|
||
|
// maintaining a widely compatible digest size with better performance on
|
||
|
// 64-bit systems.
|
||
|
//
|
||
|
// Password hashing uses bcrypt with a work factor of 14.
|
||
|
package cryptopasta
|
||
|
|
||
|
import (
|
||
|
"crypto/hmac"
|
||
|
"crypto/sha512"
|
||
|
|
||
|
"golang.org/x/crypto/bcrypt"
|
||
|
)
|
||
|
|
||
|
// Hash generates a hash of data using HMAC-SHA-512/256. The tag is intended to
|
||
|
// be a natural-language string describing the purpose of the hash, such as
|
||
|
// "hash file for lookup key" or "master secret to client secret". It serves
|
||
|
// as an HMAC "key" and ensures that different purposes will have different
|
||
|
// hash output. This function is NOT suitable for hashing passwords.
|
||
|
func Hash(tag string, data []byte) []byte {
|
||
|
h := hmac.New(sha512.New512_256, []byte(tag))
|
||
|
h.Write(data)
|
||
|
return h.Sum(nil)
|
||
|
}
|
||
|
|
||
|
// HashPassword generates a bcrypt hash of the password using work factor 14.
|
||
|
func HashPassword(password []byte) ([]byte, error) {
|
||
|
return bcrypt.GenerateFromPassword(password, 14)
|
||
|
}
|
||
|
|
||
|
// CheckPassword securely compares a bcrypt hashed password with its possible
|
||
|
// plaintext equivalent. Returns nil on success, or an error on failure.
|
||
|
func CheckPasswordHash(hash, password []byte) error {
|
||
|
return bcrypt.CompareHashAndPassword(hash, password)
|
||
|
}
|