Use sensible way of encrypting and decrypting data

This ensures the ciphertext also is authenticated.
This commit is contained in:
Leon Klingele
2017-04-11 13:07:26 +02:00
parent 041db8fe7b
commit 9657ebbe0e

View File

@@ -4,58 +4,80 @@ The previous section describes how to securely store passwords, but sometimes it
## Advanced encryption and decryption
The Go language supports symmetric encryption algorithms in its `crypto` package. Two advanced encryption modules are:
The Go language supports symmetric encryption algorithms in its `crypto` package. Do not use anything except AES in [GCM mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode) if you don't know what you're doing!
- `crypto/aes` package: AES (Advanced Encryption Standard), also known as Rijndael encryption method, is used by the U.S. federal government as a block encryption standard.
- `crypto/des` package: DES (Data Encryption Standard), is a symmetric encryption standard . It's currently the most widely used key system, especially in protecting the security of financial data. It used to be the United States federal government's encryption standard, but has now been replaced by AES.
Because using these two encryption algorithms is quite similar, we'll just use the `aes` package in the following example to demonstrate how you'd typically use these packages:
In the following example we demonstrate how to encrypt data using AES in GCM mode:
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"errors"
"fmt"
"os"
"io"
"log"
)
var commonIV = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}
func main() {
// Need to encrypt a string
plaintext := []byte("My name is Astaxie")
// If there is an incoming string of words to be encrypted, set plaintext to that incoming string
if len(os.Args) > 1 {
plaintext = []byte(os.Args[1])
}
text := []byte("My name is Astaxie")
key := []byte("the-key-has-to-be-32-bytes-long!")
// aes encryption string
key_text := "astaxie12798akljzmknm.ahkjkljl;k"
if len(os.Args) > 2 {
key_text = os.Args[2]
}
fmt.Println(len(key_text))
// Create the aes encryption algorithm
c, err := aes.NewCipher([]byte(key_text))
ciphertext, err := encrypt(text, key)
if err != nil {
fmt.Printf("Error: NewCipher(%d bytes) = %s", len(key_text), err)
os.Exit(-1)
// TODO: Properly handle error
log.Fatal(err)
}
fmt.Printf("%s => %x\n", text, ciphertext)
plaintext, err := decrypt(ciphertext, key)
if err != nil {
// TODO: Properly handle error
log.Fatal(err)
}
fmt.Printf("%x => %s\n", ciphertext, plaintext)
}
func encrypt(plaintext []byte, key []byte) ([]byte, error) {
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// Encrypted string
cfb := cipher.NewCFBEncrypter(c, commonIV)
ciphertext := make([]byte, len(plaintext))
cfb.XORKeyStream(ciphertext, plaintext)
fmt.Printf("%s=>%x\n", plaintext, ciphertext)
gcm, err := cipher.NewGCM(c)
if err != nil {
return nil, err
}
// Decrypt strings
cfbdec := cipher.NewCFBDecrypter(c, commonIV)
plaintextCopy := make([]byte, len(plaintext))
cfbdec.XORKeyStream(plaintextCopy, ciphertext)
fmt.Printf("%x=>%s\n", ciphertext, plaintextCopy)
nonce := make([]byte, gcm.NonceSize())
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
return gcm.Seal(nonce, nonce, plaintext, nil), nil
}
func decrypt(ciphertext []byte, key []byte) ([]byte, error) {
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(c)
if err != nil {
return nil, err
}
nonceSize := gcm.NonceSize()
if len(ciphertext) < nonceSize {
return nil, errors.New("ciphertext too short")
}
nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
return gcm.Open(nil, nonce, ciphertext, nil)
}
Calling the above function `aes.NewCipher` (whose []byte key parameter must be 16, 24 or 32, corresponding to the AES-128, AES-192 or AES-256 algorithms, respectively), returns a `cipher.Block` Interface that implements three functions:
@@ -77,7 +99,7 @@ These three functions implement encryption and decryption operations; see the Go
## Summary
This section describes encryption algorithms which can be used in different ways according to your web application's encryption and decryption needs. For applications with even basic security requirements it is recommended to use AES.
This section describes encryption algorithms which can be used in different ways according to your web application's encryption and decryption needs. For applications with even basic security requirements it is recommended to use AES in GCM mode.
## Links