12// Cipher provides methods to encrypt and decrypt
13type Cipher interface {
14 Encrypt(value []byte) ([]byte, error)
15 Decrypt(ciphertext []byte) ([]byte, error)
18type base64Cipher struct {
22// NewBase64Cipher returns a new AES Cipher for encrypting cookie values
23// and wrapping them in Base64 -- Supports Legacy encryption scheme
24func NewBase64Cipher(c Cipher) Cipher {
25 return &base64Cipher{Cipher: c}
28// Encrypt encrypts a value with the embedded Cipher & Base64 encodes it
29func (c *base64Cipher) Encrypt(value []byte) ([]byte, error) {
30 encrypted, err := c.Cipher.Encrypt(value)
35 return []byte(base64.StdEncoding.EncodeToString(encrypted)), nil
38// Decrypt Base64 decodes a value & decrypts it with the embedded Cipher
39func (c *base64Cipher) Decrypt(ciphertext []byte) ([]byte, error) {
40 encrypted, err := base64.StdEncoding.DecodeString(string(ciphertext))
42 return nil, fmt.Errorf("failed to base64 decode value %s", err)
45 return c.Cipher.Decrypt(encrypted)
48type cfbCipher struct {
52// NewCFBCipher returns a new AES CFB Cipher
53func NewCFBCipher(secret []byte) (Cipher, error) {
54 c, err := aes.NewCipher(secret)
58 return &cfbCipher{Block: c}, err
61// Encrypt with AES CFB
62func (c *cfbCipher) Encrypt(value []byte) ([]byte, error) {
63 ciphertext := make([]byte, aes.BlockSize+len(value))
64 iv := ciphertext[:aes.BlockSize]
65 if _, err := io.ReadFull(rand.Reader, iv); err != nil {
66 return nil, fmt.Errorf("failed to create initialization vector %s", err)
69 stream := cipher.NewCFBEncrypter(c.Block, iv)
70 stream.XORKeyStream(ciphertext[aes.BlockSize:], value)
71 return ciphertext, nil
74// Decrypt an AES CFB ciphertext
75func (c *cfbCipher) Decrypt(ciphertext []byte) ([]byte, error) {
76 if len(ciphertext) < aes.BlockSize {
77 return nil, fmt.Errorf("encrypted value should be at least %d bytes, but is only %d bytes", aes.BlockSize, len(ciphertext))
80 iv, ciphertext := ciphertext[:aes.BlockSize], ciphertext[aes.BlockSize:]
81 plaintext := make([]byte, len(ciphertext))
82 stream := cipher.NewCFBDecrypter(c.Block, iv)
83 stream.XORKeyStream(plaintext, ciphertext)
88type gcmCipher struct {
92// NewGCMCipher returns a new AES GCM Cipher
93func NewGCMCipher(secret []byte) (Cipher, error) {
94 c, err := aes.NewCipher(secret)
98 return &gcmCipher{Block: c}, err
101// Encrypt with AES GCM on raw bytes
102func (c *gcmCipher) Encrypt(value []byte) ([]byte, error) {
103 gcm, err := cipher.NewGCM(c.Block)
107 nonce := make([]byte, gcm.NonceSize())
108 if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
111 // Using nonce as Seal's dst argument results in it being the first
112 // chunk of bytes in the ciphertext. Decrypt retrieves the nonce/IV from this.
113 ciphertext := gcm.Seal(nonce, nonce, value, nil)
114 return ciphertext, nil
117// Decrypt an AES GCM ciphertext
118func (c *gcmCipher) Decrypt(ciphertext []byte) ([]byte, error) {
119 gcm, err := cipher.NewGCM(c.Block)
124 nonceSize := gcm.NonceSize()
125 nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
127 plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
131 return plaintext, nil
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list