aboutsummaryrefslogtreecommitdiff
path: root/backend/security
diff options
context:
space:
mode:
authorRyan Mehri <[email protected]>2020-05-15 17:58:09 -0600
committerRyan Mehri <[email protected]>2020-05-15 17:58:09 -0600
commit5d037e8297a192996b7281af0ca761c160aaed30 (patch)
tree68a21642cfb9396e734f16e8d636af3efdee49a0 /backend/security
parentMerge pull request #24 from jackyzha0/update-readme (diff)
downloadctrl-v-5d037e8297a192996b7281af0ca761c160aaed30.tar.xz
ctrl-v-5d037e8297a192996b7281af0ca761c160aaed30.zip
Add encryption to content when password is specified
Diffstat (limited to 'backend/security')
-rw-r--r--backend/security/encrypt.go65
-rw-r--r--backend/security/hash.go41
2 files changed, 106 insertions, 0 deletions
diff --git a/backend/security/encrypt.go b/backend/security/encrypt.go
new file mode 100644
index 0000000..fff027c
--- /dev/null
+++ b/backend/security/encrypt.go
@@ -0,0 +1,65 @@
+package security
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/rand"
+ "golang.org/x/crypto/scrypt"
+)
+
+func Encrypt(key, data []byte) ([]byte, error) {
+ blockCipher, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, err
+ }
+
+ gcm, err := cipher.NewGCM(blockCipher)
+ if err != nil {
+ return nil, err
+ }
+
+ nonce := make([]byte, gcm.NonceSize())
+ if _, err = rand.Read(nonce); err != nil {
+ return nil, err
+ }
+
+ cipherText := gcm.Seal(nonce, nonce, data, nil)
+
+ return cipherText, nil
+}
+
+func Decrypt(key, data []byte) ([]byte, error) {
+ blockCipher, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, err
+ }
+
+ gcm, err := cipher.NewGCM(blockCipher)
+ if err != nil {
+ return nil, err
+ }
+
+ nonce, cipherText := data[:gcm.NonceSize()], data[gcm.NonceSize():]
+ plaintext, err := gcm.Open(nil, nonce, cipherText, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ return plaintext, nil
+}
+
+func DeriveKey(password, salt []byte) ([]byte, []byte, error) {
+ if salt == nil {
+ salt = make([]byte, 16)
+ if _, err := rand.Read(salt); err != nil {
+ return nil, nil, err
+ }
+ }
+
+ key, err := scrypt.Key(password, salt, 16384, 8, 1, 16)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return key, salt, nil
+}
diff --git a/backend/security/hash.go b/backend/security/hash.go
new file mode 100644
index 0000000..b6ce167
--- /dev/null
+++ b/backend/security/hash.go
@@ -0,0 +1,41 @@
+package security
+
+import (
+ "crypto/md5"
+ "encoding/hex"
+ "golang.org/x/crypto/bcrypt"
+ "math/big"
+ "time"
+)
+
+const UrlLength = 7
+
+// GenerateURI creates a unique identifier for a paste based on ip and timestamp
+func GenerateURI(ip string) string {
+ timeStamp := time.Now().String()
+ return hashString(ip + timeStamp)[:UrlLength]
+}
+
+// hashes using MD5 and then converts to base 62
+func hashString(text string) string {
+ hash := md5.Sum([]byte(text))
+ hexStr := hex.EncodeToString(hash[:])
+
+ bi := big.NewInt(0)
+ bi.SetString(hexStr, 16)
+ return bi.Text(62)
+}
+
+func HashPassword(password string) (string, error) {
+ hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
+ return string(hashedPassword), err
+}
+
+func PasswordsEqual(dbPassword, parsedPassword string) bool {
+ dbPassBytes := []byte(dbPassword)
+ parsedPassBytes := []byte(parsedPassword)
+ compErr := bcrypt.CompareHashAndPassword(dbPassBytes, parsedPassBytes)
+
+ // if comparison error, the given password is not valid
+ return compErr == nil
+} \ No newline at end of file