Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- go get gitlab.com/zfeldt/gencrypt
- // NOTE: This is a wrapper around portions of the standard libraries crypto
- // package.
- // NOTE: For those deploying on systems not equipped with CPUs supporting
- // AES-NI [0], you should be aware of possible bottle-necks when it comes to
- // the AES encryption process [1].
- // >>"Final caveat, all these recommendations apply only to the amd64
- // >> architecture, for which fast, constant time implementations of the crypto
- // >> primitives (AES-GCM, ChaCha20-Poly1305, P256) are available. Other
- // >> architectures are probably not fit for production use." [1]
- // [0] https://en.wikipedia.org/wiki/AES_instruction_set#New_instructions
- // [1] https://blog.gopheracademy.com/advent-2016/exposing-go-on-the-internet/
- // Package gencrypt provides methods for encrypting and decrypting data with
- // the AES encryption method. Based on George Tankersley's talk at Gophercon
- // 2016.
- package gencrypt
- import (
- "crypto/aes"
- "crypto/cipher"
- "crypto/rand"
- )
- // Galois implements the cipher.AEAD interface type (Authenticated Encryption
- // with Associated Data), which allows us to seal and open streams of data,
- // check overhead, and check the nonce size.
- type Galois struct {
- GCM cipher.AEAD
- }
- // NewGCM takes a key and returns a new Galois struct. A 32-byte key is used to
- // indicate AES-256. 16 and 24-byte keys are accepted for AES-128 and AES-192
- // respectively, but are not recommended.
- func NewGCM(key []byte) (*Galois, error) {
- g := &Galois{}
- // Here we retrieve a new cipher.Block using the key provided. block is a
- // 128-bit block cipher (cipher.Block) used for encrypting and decrypting
- // data in individual blocks. The mode implementations (e.g. Galois Counter
- // Mode) extend that capability to streams of blocks.
- block, err := aes.NewCipher(key[:])
- if err != nil {
- return g, err
- }
- // We pass the cipher.Block to cipher.NewGCM() to retrieve a new GCM (Galois
- // Counter Mode).
- g.GCM, err = cipher.NewGCM(block)
- if err != nil {
- return g, err
- }
- // We return the Galois struct containing the GCM so that it can be used for
- // encryption and decryption by the client.
- return g, nil
- }
- // AESEncrypt is a method of the Galois struct which encrypts data using the
- // mode (GCM) and returns an encrypted []byte.
- func (g *Galois) AESEncrypt(data []byte) ([]byte, error) {
- // We use the gcm.NonceSize() method to create a byte slice with the
- // appropriate nonce length, then use the rand.Read() method to write random
- // bytes to the slice, thus creating our nonce.
- nonce := make([]byte, g.GCM.NonceSize())
- _, err := rand.Read(nonce)
- if err != nil {
- return nil, err
- }
- // gcm.Seal() returns a []byte containing the encrypted data. The nonce is
- // used both as the dst []byte, which encrypted data is appended to, and to
- // derive the initial GCM counter state (for more details see the
- // cipher/gcm.go file in the Go source code).
- return g.GCM.Seal(nonce, nonce, data, nil), nil
- }
- // AESDecrypt is a method of the Galois struct which decrypts data using the
- // mode (GCM) and returns a decrypted []byte, which can be converted to a type
- // (e.g. string) of the original data.
- func (g *Galois) AESDecrypt(data []byte) ([]byte, error) {
- // We return the decrypted data by passing it through gcm.Open(). Remember:
- // the data argument contains the nonce at the beginning of the slice, and
- // has the encrypted data appended after it, as seen below. The decrypted
- // data is returned as a []byte that can then be converted into its original
- // form.
- return g.GCM.Open(nil, data[:g.GCM.NonceSize()], data[g.GCM.NonceSize():], nil)
- }
- gcm, _ := gencrypt.NewGCM(key)
- encryptedData, _ := gcm.AESEncrypt(data)
- gcm, _ := gencrypt.NewGCM(key)
- encryptedData. _ := gencrypt.AESEncrypt(gcm, data) // this line changed
Add Comment
Please, Sign In to add comment