From 88535c8fbe0199f6907aef58f0a29faaa2648831 Mon Sep 17 00:00:00 2001 From: Pierre Carrier Date: Thu, 21 Nov 2013 13:13:27 -0800 Subject: [PATCH] support for encryption --- README.md | 25 ++++++++++++++++++++++++- gauth.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b30ad00..8581a45 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Usage - Run `gauth`. The progress bar indicates how far the next change is. - ~$ gauth + $ gauth prev curr next AWS 315306 135387 483601 Airbnb 563728 339206 904549 @@ -33,8 +33,31 @@ Usage Github 911264 548790 784099 [======= ] +- `gauth` is convenient to use in `watch`. + + $ watch -n1 gauth + - Remember to keep your system clock synchronized and to **lock your computer when brewing your tea!** +Encryption +---------- + +`gauth` supports password-based encryption of `gauth.csv`. To encrypt, use: + + $ openssl enc -aes-128-cbc -md sha256 -in gauth.csv -out ~/.config/gauth.csv + enter aes-128-cbc encryption password: + Verifying - enter aes-128-cbc encryption password: + +`gauth` will then prompt you for that password on every run: + + $ gauth + Encryption password: + prev curr next + LastPass 915200 479333 408710 + +Note that this encryption mechanism is far from ideal from a pure security standpoint. +Please read [OpenSSL's notes on the subject](http://www.openssl.org/docs/crypto/EVP_BytesToKey.html#NOTES). + Compatibility ------------- diff --git a/gauth.go b/gauth.go index 5c1297d..eb5bad7 100644 --- a/gauth.go +++ b/gauth.go @@ -2,8 +2,12 @@ package main import ( "bytes" + "code.google.com/p/gopass" + "crypto/aes" + "crypto/cipher" "crypto/hmac" "crypto/sha1" + "crypto/sha256" "encoding/base32" "encoding/csv" "fmt" @@ -77,6 +81,35 @@ func main() { log.Fatal(e) } + // Support for 'openssl enc -aes-128-cbc -md sha256 -pass pass:' + if bytes.Compare(cfgContent[:8], []byte{0x53, 0x61, 0x6c, 0x74, 0x65, 0x64, 0x5f, 0x5f}) == 0 { + passwd, e := gopass.GetPass("Encryption password: ") + if e != nil { + log.Fatal(e) + } + salt := cfgContent[8:16] + rest := cfgContent[16:] + salting := sha256.New() + salting.Write([]byte(passwd)) + salting.Write(salt) + sum := salting.Sum(nil) + key := sum[:16] + iv := sum[16:] + block, e := aes.NewCipher(key) + if e != nil { + log.Fatal(e) + } + + mode := cipher.NewCBCDecrypter(block, iv) + mode.CryptBlocks(rest, rest) + // Remove padding + i := len(rest) + for rest[i] < 16 { + i-- + } + cfgContent = rest[:i] + } + cfgReader := csv.NewReader(bytes.NewReader(cfgContent)) // Unix-style tabular cfgReader.Comma = ':'