From c7e37649d2012b0970a99d1de95e859c8f4ba7c1 Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 10 Sep 2016 07:45:36 -0400 Subject: [PATCH] Passwords stored as hashes instead of on the server Former-commit-id: 8e42d0aad6b21a4378f2881c80a25786aaec3fca [formerly 1a169ed9ce9372babf129ee16e782cd5a7ebf960] [formerly 23767ee90357ba8a46cf2bcb24f43dabc951dbc7 [formerly ccfe66e973920ddac0edcb1cfe33ad6c58d8bb0e]] Former-commit-id: 2f1dcbda58dec1ff16dd783711ea8401932d1e37 [formerly 6420a2b52256cfec0edf10b478f99483b49b76bb] Former-commit-id: 7b8c830459c262958272bcb5c9661f7d5a57a86d --- README.md | 2 +- routes.go | 7 +++++-- utils.go | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a5e457d..272760f 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ This is a self-contained notepad webserver that makes sharing easy and _fast_. T
-**Self-destructing messages**. You can write a message that will delete itself when a user loads it (in any view). Useful for transmitting sensitive information. To use, simply add a line somewhere that says only "`self-destruct`". +**Self-destructing messages**. You can write a message [that will delete itself](https://github.com/schollz/cowyo/blob/master/routes.go#L550-L553) when a user loads it (in any view). Useful for transmitting sensitive information. To use, simply add a line somewhere that says only "`self-destruct`". ![Mission impossible style self-destruction.](https://raw.githubusercontent.com/schollz/cowyo/master/static/img/help5.gif) diff --git a/routes.go b/routes.go index b16ccc7..c7fccec 100644 --- a/routes.go +++ b/routes.go @@ -149,7 +149,8 @@ func encryptionRoute(c *gin.Context) { if err != nil { panic(err) } - p.Locked = jsonLoad.Password + hashedPassword, _ := HashPassword([]byte(jsonLoad.Password)) + p.Locked = string(hashedPassword) p.save(p.CurrentText) c.JSON(200, gin.H{ "status": "posted", @@ -173,7 +174,9 @@ func encryptionRoute(c *gin.Context) { if err != nil { panic(err) } - if len(p.Locked) > 0 && p.Locked == jsonLoad.Password { + if len(p.Locked) > 0 && + (p.Locked == jsonLoad.Password || + CheckPasswordHash([]byte(p.Locked), []byte(jsonLoad.Password)) == nil) { p.Locked = "" p.save(p.CurrentText) c.JSON(200, gin.H{ diff --git a/utils.go b/utils.go index b921119..0a795d2 100644 --- a/utils.go +++ b/utils.go @@ -11,6 +11,8 @@ import ( "strings" "time" + "golang.org/x/crypto/bcrypt" + "github.com/jcelliott/lumber" "github.com/sergi/go-diff/diffmatchpatch" ) @@ -236,3 +238,16 @@ func GetLocalIP() string { } return bestIP } + +// HashPassword generates a bcrypt hash of the password using work factor 14. +// https://github.com/gtank/cryptopasta/blob/master/hash.go +func HashPassword(password []byte) ([]byte, error) { + return bcrypt.GenerateFromPassword(password, 14) +} + +// CheckPassword securely compares a bcrypt hashed password with its possible +// plaintext equivalent. Returns nil on success, or an error on failure. +// https://github.com/gtank/cryptopasta/blob/master/hash.go +func CheckPasswordHash(hash, password []byte) error { + return bcrypt.CompareHashAndPassword(hash, password) +}