diff options
Diffstat (limited to 'internal/cryptoutil')
-rw-r--r-- | internal/cryptoutil/aes.go | 56 | ||||
-rw-r--r-- | internal/cryptoutil/aes_test.go | 34 | ||||
-rw-r--r-- | internal/cryptoutil/md5.go | 22 | ||||
-rw-r--r-- | internal/cryptoutil/md5_test.go | 27 |
4 files changed, 139 insertions, 0 deletions
diff --git a/internal/cryptoutil/aes.go b/internal/cryptoutil/aes.go new file mode 100644 index 00000000..ec037b64 --- /dev/null +++ b/internal/cryptoutil/aes.go @@ -0,0 +1,56 @@ +// Copyright 2020 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package cryptoutil + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "errors" +) + +// AESGCMEncrypt encrypts plaintext with the given key using AES in GCM mode. +func AESGCMEncrypt(key, plaintext []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + + nonce := make([]byte, gcm.NonceSize()) + if _, err := rand.Read(nonce); err != nil { + return nil, err + } + + ciphertext := gcm.Seal(nil, nonce, plaintext, nil) + return append(nonce, ciphertext...), nil +} + +// AESGCMDecrypt decrypts ciphertext with the given key using AES in GCM mode. +func AESGCMDecrypt(key, ciphertext []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + + size := gcm.NonceSize() + if len(ciphertext)-size <= 0 { + return nil, errors.New("ciphertext is empty") + } + + nonce := ciphertext[:size] + ciphertext = ciphertext[size:] + + return gcm.Open(nil, nonce, ciphertext, nil) +} diff --git a/internal/cryptoutil/aes_test.go b/internal/cryptoutil/aes_test.go new file mode 100644 index 00000000..0e34bcb0 --- /dev/null +++ b/internal/cryptoutil/aes_test.go @@ -0,0 +1,34 @@ +// Copyright 2020 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package cryptoutil + +import ( + "crypto/rand" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestAESGCM(t *testing.T) { + key := make([]byte, 16) // AES-128 + _, err := rand.Read(key) + if err != nil { + t.Fatal(err) + } + + plaintext := []byte("this will be encrypted") + + encrypted, err := AESGCMEncrypt(key, plaintext) + if err != nil { + t.Fatal(err) + } + + decrypted, err := AESGCMDecrypt(key, encrypted) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, plaintext, decrypted) +} diff --git a/internal/cryptoutil/md5.go b/internal/cryptoutil/md5.go new file mode 100644 index 00000000..249f3ed5 --- /dev/null +++ b/internal/cryptoutil/md5.go @@ -0,0 +1,22 @@ +// Copyright 2020 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package cryptoutil + +import ( + "crypto/md5" + "encoding/hex" +) + +// MD5 encodes string to hexadecimal of MD5 checksum. +func MD5(str string) string { + return hex.EncodeToString(MD5Bytes(str)) +} + +// MD5Bytes encodes string to MD5 checksum. +func MD5Bytes(str string) []byte { + m := md5.New() + _, _ = m.Write([]byte(str)) + return m.Sum(nil) +} diff --git a/internal/cryptoutil/md5_test.go b/internal/cryptoutil/md5_test.go new file mode 100644 index 00000000..d3986a32 --- /dev/null +++ b/internal/cryptoutil/md5_test.go @@ -0,0 +1,27 @@ +// Copyright 2020 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package cryptoutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMD5(t *testing.T) { + tests := []struct { + input string + output string + }{ + {input: "", output: "d41d8cd98f00b204e9800998ecf8427e"}, + {input: "The quick brown fox jumps over the lazy dog", output: "9e107d9d372bb6826bd81d3542a419d6"}, + {input: "The quick brown fox jumps over the lazy dog.", output: "e4d909c290d0fb1ca068ffaddf22cbd0"}, + } + for _, test := range tests { + t.Run(test.input, func(t *testing.T) { + assert.Equal(t, test.output, MD5(test.input)) + }) + } +} |