Ver Fonte

use PBKDF2 to esnure key is 23bytes.

Anthony Woods há 10 anos atrás
pai
commit
c8c337cead
2 ficheiros alterados com 17 adições e 18 exclusões
  1. 15 15
      pkg/util/encryption.go
  2. 2 3
      pkg/util/encryption_test.go

+ 15 - 15
pkg/util/encryption.go

@@ -4,13 +4,17 @@ import (
 	"crypto/aes"
 	"crypto/aes"
 	"crypto/cipher"
 	"crypto/cipher"
 	"crypto/rand"
 	"crypto/rand"
+	"crypto/sha256"
 	"io"
 	"io"
 
 
 	"github.com/grafana/grafana/pkg/log"
 	"github.com/grafana/grafana/pkg/log"
 )
 )
 
 
+const saltLength = 8
+
 func Decrypt(payload []byte, secret string) []byte {
 func Decrypt(payload []byte, secret string) []byte {
-	key := encryptionKeyToBytes(secret)
+	salt := payload[:saltLength]
+	key := encryptionKeyToBytes(secret, string(salt))
 
 
 	block, err := aes.NewCipher(key)
 	block, err := aes.NewCipher(key)
 	if err != nil {
 	if err != nil {
@@ -22,8 +26,8 @@ func Decrypt(payload []byte, secret string) []byte {
 	if len(payload) < aes.BlockSize {
 	if len(payload) < aes.BlockSize {
 		log.Fatal(4, "payload too short")
 		log.Fatal(4, "payload too short")
 	}
 	}
-	iv := payload[:aes.BlockSize]
-	payload = payload[aes.BlockSize:]
+	iv := payload[saltLength : saltLength+aes.BlockSize]
+	payload = payload[saltLength+aes.BlockSize:]
 
 
 	stream := cipher.NewCFBDecrypter(block, iv)
 	stream := cipher.NewCFBDecrypter(block, iv)
 
 
@@ -33,8 +37,9 @@ func Decrypt(payload []byte, secret string) []byte {
 }
 }
 
 
 func Encrypt(payload []byte, secret string) []byte {
 func Encrypt(payload []byte, secret string) []byte {
-	key := encryptionKeyToBytes(secret)
+	salt := GetRandomString(saltLength)
 
 
+	key := encryptionKeyToBytes(secret, salt)
 	block, err := aes.NewCipher(key)
 	block, err := aes.NewCipher(key)
 	if err != nil {
 	if err != nil {
 		log.Fatal(4, err.Error())
 		log.Fatal(4, err.Error())
@@ -42,25 +47,20 @@ func Encrypt(payload []byte, secret string) []byte {
 
 
 	// The IV needs to be unique, but not secure. Therefore it's common to
 	// The IV needs to be unique, but not secure. Therefore it's common to
 	// include it at the beginning of the ciphertext.
 	// include it at the beginning of the ciphertext.
-	ciphertext := make([]byte, aes.BlockSize+len(payload))
-	iv := ciphertext[:aes.BlockSize]
+	ciphertext := make([]byte, saltLength+aes.BlockSize+len(payload))
+	copy(ciphertext[:saltLength], []byte(salt))
+	iv := ciphertext[saltLength : saltLength+aes.BlockSize]
 	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
 	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
 		log.Fatal(4, err.Error())
 		log.Fatal(4, err.Error())
 	}
 	}
 
 
 	stream := cipher.NewCFBEncrypter(block, iv)
 	stream := cipher.NewCFBEncrypter(block, iv)
-	stream.XORKeyStream(ciphertext[aes.BlockSize:], payload)
+	stream.XORKeyStream(ciphertext[saltLength+aes.BlockSize:], payload)
 
 
 	return ciphertext
 	return ciphertext
 }
 }
 
 
 // Key needs to be 32bytes
 // 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++ {
-		key[i] = keyBytes[i%secretLength]
-	}
-	return key
+func encryptionKeyToBytes(secret, salt string) []byte {
+	return PBKDF2([]byte(secret), []byte(salt), 10000, 32, sha256.New)
 }
 }

+ 2 - 3
pkg/util/encryption_test.go

@@ -10,12 +10,11 @@ func TestEncryption(t *testing.T) {
 
 
 	Convey("When getting encryption key", t, func() {
 	Convey("When getting encryption key", t, func() {
 
 
-		key := encryptionKeyToBytes("secret")
+		key := encryptionKeyToBytes("secret", "salt")
 		So(len(key), ShouldEqual, 32)
 		So(len(key), ShouldEqual, 32)
 
 
-		key = encryptionKeyToBytes("a very long secret key that is larger then 32bytes")
+		key = encryptionKeyToBytes("a very long secret key that is larger then 32bytes", "salt")
 		So(len(key), ShouldEqual, 32)
 		So(len(key), ShouldEqual, 32)
-
 	})
 	})
 
 
 	Convey("When decrypting basic payload", t, func() {
 	Convey("When decrypting basic payload", t, func() {