Files
heicode-mananger/heicode/common/crypto.go
T

71 lines
2.1 KiB
Go

package common
import (
"crypto/ed25519"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"errors"
"golang.org/x/crypto/bcrypt"
)
func GenerateHMACWithKey(key []byte, data string) string {
h := hmac.New(sha256.New, key)
h.Write([]byte(data))
return hex.EncodeToString(h.Sum(nil))
}
func GenerateHMAC(data string) string {
h := hmac.New(sha256.New, []byte(CryptoSecret))
h.Write([]byte(data))
return hex.EncodeToString(h.Sum(nil))
}
func Password2Hash(password string) (string, error) {
passwordBytes := []byte(password)
hashedPassword, err := bcrypt.GenerateFromPassword(passwordBytes, bcrypt.DefaultCost)
return string(hashedPassword), err
}
func ValidatePasswordAndHash(password string, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}
// VerifyEd25519Signature validates a base64-encoded Ed25519 signature over
// the given message bytes, using a base64-encoded 32-byte public key.
// Returns nil if valid, otherwise an error describing what failed.
//
// Used by the device-signature middleware to authenticate per-request
// signatures from device-bound Heicode clients. The client signs the
// SHA-256 hash of a canonical request string; this helper just does the
// raw Ed25519 verify and surface-level decode.
func VerifyEd25519Signature(pubkeyB64 string, message []byte, signatureB64 string) error {
if pubkeyB64 == "" {
return errors.New("empty public key")
}
if signatureB64 == "" {
return errors.New("empty signature")
}
pubkey, err := base64.StdEncoding.DecodeString(pubkeyB64)
if err != nil {
return errors.New("public key is not valid base64")
}
if len(pubkey) != ed25519.PublicKeySize {
return errors.New("public key has wrong length")
}
sig, err := base64.StdEncoding.DecodeString(signatureB64)
if err != nil {
return errors.New("signature is not valid base64")
}
if len(sig) != ed25519.SignatureSize {
return errors.New("signature has wrong length")
}
if !ed25519.Verify(ed25519.PublicKey(pubkey), message, sig) {
return errors.New("signature did not verify")
}
return nil
}