61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package simplebox
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"fmt"
|
|
|
|
"golang.org/x/crypto/nacl/secretbox"
|
|
)
|
|
|
|
const (
|
|
// Length in bytes of a secret key used for encryption and decryption.
|
|
KeySize = 32
|
|
|
|
// Length in bytes of a nonce value (which must be unique and may be
|
|
// random) used for encryption and decryption.
|
|
NonceSize = 24
|
|
)
|
|
|
|
// SimpleBox provides a simple wrapper around NaCl's secretbox with a
|
|
// self-contained random nonce strategy.
|
|
type SimpleBox struct {
|
|
secretKey *[KeySize]byte
|
|
}
|
|
|
|
// Creates a SimpleBox from a secret key.
|
|
func NewFromSecretKey(secretKey *[KeySize]byte) *SimpleBox {
|
|
return &SimpleBox{secretKey: secretKey}
|
|
}
|
|
|
|
// Decrypts the given ciphertext and returns plaintext. An appropriate error is
|
|
// included if decryption failed.
|
|
func (b *SimpleBox) Decrypt(cipher []byte) ([]byte, error) {
|
|
if len(cipher) <= NonceSize {
|
|
return nil, fmt.Errorf("Ciphertext is of invalid length.")
|
|
}
|
|
|
|
var nonce [NonceSize]byte
|
|
copy(nonce[:], cipher[0:NonceSize])
|
|
payload := cipher[NonceSize:]
|
|
|
|
var opened []byte
|
|
opened, ok := secretbox.Open(opened[:0], payload, &nonce, b.secretKey)
|
|
|
|
if !ok {
|
|
return nil, fmt.Errorf("Ciphertext could not be decrypted.")
|
|
}
|
|
|
|
return opened, nil
|
|
}
|
|
|
|
// Encrypts the given plaintext and returns ciphertext.
|
|
func (b *SimpleBox) Encrypt(plain []byte) []byte {
|
|
var nonce [NonceSize]byte
|
|
rand.Reader.Read(nonce[:])
|
|
|
|
var box []byte
|
|
box = secretbox.Seal(box[:0], plain, &nonce, b.secretKey)
|
|
|
|
return append(nonce[:], box...)
|
|
}
|