Skip to content

Instantly share code, notes, and snippets.

@jlturner
Created July 29, 2014 03:08
Show Gist options
  • Save jlturner/22523bbce3d820337099 to your computer and use it in GitHub Desktop.
Save jlturner/22523bbce3d820337099 to your computer and use it in GitHub Desktop.
Encoding & Decoding messages using secretbox (http://nacl.cr.yp.to/secretbox.html)
package main
// Deps:
// code.google.com/p/go.crypto/nacl/secretbox
import (
"code.google.com/p/go.crypto/nacl/secretbox"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"strings"
)
func nonceSliceToArray(nonceSlice []byte) (nonce [24]byte) {
for i, b := range nonceSlice {
nonce[i] = b
}
return
}
func encryptMessage(message string, secretKey *[32]byte, delimiter string) (string, error) {
// Generate a nonce
nonceSlice := make([]byte, 24)
_, err := rand.Read(nonceSlice)
if err != nil {
return "", err
}
nonce := nonceSliceToArray(nonceSlice)
// Encrypt message with nonce and secret key
encryptedBytes := secretbox.Seal([]byte(""), []byte(message), &nonce, secretKey)
// Return the final encrypted message (base64 encoded cyphertext and nonce, separated by delimiter)
base64Cyphertext := base64.StdEncoding.EncodeToString(encryptedBytes)
base64Nonce := base64.StdEncoding.EncodeToString(nonceSlice)
return strings.Join([]string{base64Cyphertext, base64Nonce}, delimiter), nil
}
func decryptMessage(message string, secretKey *[32]byte, delimiter string) (string, error) {
// Split on the delimiter to get the cypher text and the nonce
parts := strings.Split(message, delimiter)
// Base64 Decode the cyphertext and nonce
cyphertext, err := base64.StdEncoding.DecodeString(parts[0])
if err != nil {
return "", err
}
nonceSlice, err := base64.StdEncoding.DecodeString(parts[1])
if err != nil {
return "", err
}
nonce := nonceSliceToArray(nonceSlice)
// Decrypt the cypher text with the nonce and secret key
var output []byte
decryptedBytes, decryptionSuccessful := secretbox.Open(output, cyphertext, &nonce, secretKey)
if decryptionSuccessful != true {
return "", errors.New("Could not decrypt cyphertext.")
} else {
return string(decryptedBytes), nil
}
}
func generateSecretKey() *[32]byte {
secretKeySlice := make([]byte, 32)
_, err := rand.Read(secretKeySlice)
if err != nil {
panic(err.Error())
}
var secretKey [32]byte
for i, b := range secretKeySlice {
secretKey[i] = b
}
return &secretKey
}
func main() {
secretKey := generateSecretKey()
message := "Dogs don't give a fuck"
fmt.Println("Input given: ", message)
encrypted, _ := encryptMessage(message, secretKey, "$")
fmt.Println("Encrypted as:", encrypted)
decrypted, _ := decryptMessage(encrypted, secretKey, "$")
fmt.Println("Decrypted as:", decrypted)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment