mirror of
https://github.com/openziti/zrok.git
synced 2026-08-24 10:14:56 -05:00
59 lines
1.5 KiB
Go
59 lines
1.5 KiB
Go
package endpoints
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"fmt"
|
|
|
|
"github.com/go-jose/go-jose/v4"
|
|
"golang.org/x/crypto/hkdf"
|
|
)
|
|
|
|
// DeriveKey uses HKDF to expand a "password" into a []byte to be used as a key; better than just a raw hash
|
|
func DeriveKey(keyString string, sz int) ([]byte, error) {
|
|
out := hkdf.New(sha256.New, []byte(keyString), nil, []byte("derived-key"))
|
|
key := make([]byte, sz)
|
|
_, err := out.Read(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return key, nil
|
|
}
|
|
|
|
// EncryptToken uses AES-GCM (256) to encrypt tokens for inclusion in session tokens so that they're opaque outside of
|
|
// the auth subsystem
|
|
func EncryptToken(token string, key []byte) (string, error) {
|
|
enc, err := jose.NewEncrypter(
|
|
jose.A256GCM,
|
|
jose.Recipient{
|
|
Algorithm: jose.DIRECT,
|
|
Key: key,
|
|
},
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to create encrypter: %v", err)
|
|
}
|
|
|
|
obj, err := enc.Encrypt([]byte(token))
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to encrypt token: %v", err)
|
|
}
|
|
|
|
return obj.CompactSerialize()
|
|
}
|
|
|
|
// DecryptToken decrypts a token that was encrypted with EncryptToken
|
|
func DecryptToken(encrypted string, key []byte) (string, error) {
|
|
obj, err := jose.ParseEncrypted(encrypted, []jose.KeyAlgorithm{jose.DIRECT}, []jose.ContentEncryption{jose.A256GCM})
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to parse encrypted token: %v", err)
|
|
}
|
|
|
|
decrypted, err := obj.Decrypt(key)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to decrypt token: %v", err)
|
|
}
|
|
|
|
return string(decrypted), nil
|
|
}
|