github.com/nais/knorten@v0.0.0-20240104110906-55926958e361/pkg/database/crypto/crypto.go (about)

     1  package crypto
     2  
     3  import (
     4  	"crypto/aes"
     5  	"crypto/cipher"
     6  	"crypto/rand"
     7  	"encoding/hex"
     8  	"io"
     9  )
    10  
    11  type EncrypterDecrypter struct {
    12  	key []byte
    13  }
    14  
    15  func New(key string) *EncrypterDecrypter {
    16  	return &EncrypterDecrypter{
    17  		key: []byte(key),
    18  	}
    19  }
    20  
    21  func (ed *EncrypterDecrypter) EncryptValue(value string) (string, error) {
    22  	aesBlock, err := aes.NewCipher(ed.key)
    23  	if err != nil {
    24  		return "", err
    25  	}
    26  
    27  	gcm, err := cipher.NewGCM(aesBlock)
    28  	if err != nil {
    29  		return "", err
    30  	}
    31  
    32  	nonce := make([]byte, gcm.NonceSize())
    33  	_, err = io.ReadFull(rand.Reader, nonce)
    34  	if err != nil {
    35  		return "", err
    36  	}
    37  
    38  	encrypted := gcm.Seal(nonce, nonce, []byte(value), nil)
    39  	return hex.EncodeToString(encrypted), nil
    40  }
    41  
    42  func (ed *EncrypterDecrypter) DecryptValue(encValue string) (string, error) {
    43  	encBytes, err := hex.DecodeString(encValue)
    44  	if err != nil {
    45  		return "", err
    46  	}
    47  
    48  	aesBlock, err := aes.NewCipher(ed.key)
    49  	if err != nil {
    50  		return "", err
    51  	}
    52  
    53  	gcm, err := cipher.NewGCM(aesBlock)
    54  	if err != nil {
    55  		return "", err
    56  	}
    57  
    58  	nonceSize := gcm.NonceSize()
    59  	nonce, cipheredText := encBytes[:nonceSize], encBytes[nonceSize:]
    60  
    61  	value, err := gcm.Open(nil, nonce, cipheredText, nil)
    62  	if err != nil {
    63  		return "", err
    64  	}
    65  	return string(value), nil
    66  }