Skip to content

Instantly share code, notes, and snippets.

@jooyunghan
Created September 18, 2018 17:30
Show Gist options
  • Save jooyunghan/f17429c6259807baa57e1d95ab25e7cb to your computer and use it in GitHub Desktop.
Save jooyunghan/f17429c6259807baa57e1d95ab25e7cb to your computer and use it in GitHub Desktop.
Crypto example in Go
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
)
func main() {
key := make([]byte, 24) // 16, 24, 32:
if _, err := rand.Read(key); err != nil {
panic(err)
}
s1 := "hello world"
fmt.Println("encrypt", s1)
encrypted, _ := encrypt(key, []byte(s1))
fmt.Println("==>", encrypted)
s2, _ := decrypt(key, encrypted)
fmt.Println("decrypt", string(s2))
}
func encrypt(key, data []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// make random []byte for IV
iv := make([]byte, block.BlockSize())
if _, err := rand.Read(iv); err != nil {
return nil, err
}
// data should be padded to be multiples of BlockSize
data = pad(data, block.BlockSize())
cipher.NewCBCEncrypter(block, iv).CryptBlocks(data, data)
// prepend IV to encrypted []byte
return append(iv, data...), nil
}
func decrypt(key, data []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// detach prepended IV from data
iv, data := data[:block.BlockSize()], data[block.BlockSize():]
cipher.NewCBCDecrypter(block, iv).CryptBlocks(data, data)
// remove padding
return unpad(data), nil
}
func pad(b []byte, blockSize int) []byte {
// see https://tools.ietf.org/html/rfc5246#section-6.2.3.2
padLen := blockSize - (len(b) % blockSize)
padding := bytes.Repeat([]byte{byte(padLen)}, padLen)
return append(padding, b...)
}
func unpad(b []byte) []byte {
return b[int(b[0]):]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment