Explorar o código

add encryption util functions

Anthony Woods %!s(int64=10) %!d(string=hai) anos
pai
achega
ab3b586838
Modificáronse 2 ficheiros con 98 adicións e 0 borrados
  1. 70 0
      pkg/util/encryption.go
  2. 28 0
      pkg/util/encryption_test.go

+ 70 - 0
pkg/util/encryption.go

@@ -0,0 +1,70 @@
+package util
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/rand"
+	"io"
+
+	"github.com/grafana/grafana/pkg/log"
+)
+
+func Decrypt(payload []byte, secret string) []byte {
+	key := encryptionKeyToBytes(secret)
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		log.Fatal(4, err.Error())
+	}
+
+	// The IV needs to be unique, but not secure. Therefore it's common to
+	// include it at the beginning of the ciphertext.
+	if len(payload) < aes.BlockSize {
+		log.Fatal(4, "payload too short")
+	}
+	iv := payload[:aes.BlockSize]
+	payload = payload[aes.BlockSize:]
+
+	stream := cipher.NewCFBDecrypter(block, iv)
+
+	// XORKeyStream can work in-place if the two arguments are the same.
+	stream.XORKeyStream(payload, payload)
+	return payload
+}
+
+func Encrypt(payload []byte, secret string) []byte {
+	key := encryptionKeyToBytes(secret)
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		log.Fatal(4, err.Error())
+	}
+
+	// The IV needs to be unique, but not secure. Therefore it's common to
+	// include it at the beginning of the ciphertext.
+	ciphertext := make([]byte, aes.BlockSize+len(payload))
+	iv := ciphertext[:aes.BlockSize]
+	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
+		log.Fatal(4, err.Error())
+	}
+
+	stream := cipher.NewCFBEncrypter(block, iv)
+	stream.XORKeyStream(ciphertext[aes.BlockSize:], payload)
+
+	return ciphertext
+}
+
+// Key needs to be 32bytes
+func encryptionKeyToBytes(secret string) []byte {
+	key := make([]byte, 32, 32)
+	keyBytes := []byte(secret)
+	secretLength := len(keyBytes)
+	for i := 0; i < 32; i++ {
+		if secretLength > i {
+			key[i] = keyBytes[i]
+		} else {
+			key[i] = 0
+		}
+	}
+	return key
+}

+ 28 - 0
pkg/util/encryption_test.go

@@ -0,0 +1,28 @@
+package util
+
+import (
+	"testing"
+
+	. "github.com/smartystreets/goconvey/convey"
+)
+
+func TestEncryption(t *testing.T) {
+
+	Convey("When getting encryption key", t, func() {
+
+		key := encryptionKeyToBytes("secret")
+		So(len(key), ShouldEqual, 32)
+
+		key = encryptionKeyToBytes("a very long secret key that is larger then 32bytes")
+		So(len(key), ShouldEqual, 32)
+
+	})
+
+	Convey("When decrypting basic payload", t, func() {
+		encrypted := Encrypt([]byte("grafana"), "1234")
+		decrypted := Decrypt(encrypted, "1234")
+
+		So(string(decrypted), ShouldEqual, "grafana")
+	})
+
+}