浏览代码

added encryption and encoding

bmallred 10 年之前
父节点
当前提交
7167b5c7cc
共有 5 个文件被更改,包括 135 次插入43 次删除
  1. 二进制
      084e0343a0486ff05530df6c705c8bb4
  2. 11 0
      file.go
  3. 45 38
      handlers.go
  4. 1 1
      main.go
  5. 78 4
      security.go

二进制
084e0343a0486ff05530df6c705c8bb4


+ 11 - 0
file.go

24
	if err != nil {
24
	if err != nil {
25
		return err
25
		return err
26
	}
26
	}
27
	b, err = encrypt(encodeBase64(b), passphrase)
28
	if err != nil {
29
		return err
30
	}
27
31
28
	// Compress the contents
32
	// Compress the contents
29
	var buffer bytes.Buffer
33
	var buffer bytes.Buffer
69
	decompressed, err := ioutil.ReadAll(gzip)
73
	decompressed, err := ioutil.ReadAll(gzip)
70
	gzip.Close()
74
	gzip.Close()
71
75
76
	// Decrypt the contents
77
	decompressed, err = decrypt(decompressed, passphrase)
78
	if err != nil {
79
		return nil, err
80
	}
81
	decompressed = decodeBase64(decompressed)
82
72
	// Unmarshal the JSON information
83
	// Unmarshal the JSON information
73
	var sites []Site
84
	var sites []Site
74
	err = json.Unmarshal(decompressed, &sites)
85
	err = json.Unmarshal(decompressed, &sites)

+ 45 - 38
handlers.go

7
	"os"
7
	"os"
8
	"strconv"
8
	"strconv"
9
	"text/template"
9
	"text/template"
10
	"time"
10
)
11
)
11
12
12
type Page struct {
13
type Page struct {
31
		return
32
		return
32
	}
33
	}
33
34
35
	passphrase = string(decodeBase64([]byte(passphrase)))
36
34
	u, err := url.Parse(host)
37
	u, err := url.Parse(host)
35
	if err != nil {
38
	if err != nil {
36
		http.Error(w, err.Error(), http.StatusInternalServerError)
39
		http.Error(w, err.Error(), http.StatusInternalServerError)
81
		return
84
		return
82
	}
85
	}
83
86
84
	book := getBookname(profile)
87
	passphrase = string(decodeBase64([]byte(passphrase)))
85
88
86
	if cmd == "delete" {
89
	switch cmd {
90
	default:
91
		// This should never happen, but just in case send them back
92
		http.Redirect(w, r, "/book", http.StatusSeeOther)
93
		return
94
	case "delete":
95
		book := getBookname(profile)
87
		err := os.Remove(book)
96
		err := os.Remove(book)
88
		if err != nil {
97
		if err != nil {
89
			// Return an error
98
			// Return an error
92
		}
101
		}
93
102
94
		http.Redirect(w, r, "/", http.StatusSeeOther)
103
		http.Redirect(w, r, "/", http.StatusSeeOther)
95
	} else if cmd == "update" {
104
		break
105
	case "update":
96
		if newPassphrase == "" || confirmPassphrase == "" || newPassphrase != confirmPassphrase {
106
		if newPassphrase == "" || confirmPassphrase == "" || newPassphrase != confirmPassphrase {
97
			http.Error(w, "Invalid passphrase provided", http.StatusInternalServerError)
107
			http.Error(w, "Invalid passphrase provided", http.StatusInternalServerError)
98
			return
108
			return
99
		}
109
		}
100
110
111
		book := getBookname(profile)
101
		sites, err := read(book, passphrase)
112
		sites, err := read(book, passphrase)
102
		if err != nil {
113
		if err != nil {
103
			http.Error(w, err.Error(), http.StatusInternalServerError)
114
			http.Error(w, err.Error(), http.StatusInternalServerError)
109
			return
120
			return
110
		}
121
		}
111
122
112
		http.Redirect(w, r, "/book", http.StatusSeeOther)
113
	} else {
114
		// This should never happen, but just in case send them back
115
		http.Redirect(w, r, "/book", http.StatusSeeOther)
123
		cookiePassphrase := &http.Cookie{
124
			Name:   "passphrase",
125
			MaxAge: -1,
126
		}
127
		http.SetCookie(w, cookiePassphrase)
128
		http.Redirect(w, r, "/", http.StatusSeeOther)
129
		break
116
	}
130
	}
117
}
131
}
118
132
126
		return
140
		return
127
	}
141
	}
128
142
143
	passphrase = string(decodeBase64([]byte(passphrase)))
144
129
	// Update the revision number and generate a new password
145
	// Update the revision number and generate a new password
130
	book := getBookname(profile)
146
	book := getBookname(profile)
131
	sites, err := read(book, passphrase)
147
	sites, err := read(book, passphrase)
158
		return
174
		return
159
	}
175
	}
160
176
177
	passphrase = string(decodeBase64([]byte(passphrase)))
178
161
	// Remove the site from our book and save it
179
	// Remove the site from our book and save it
162
	book := getBookname(profile)
180
	book := getBookname(profile)
163
	sites, err := read(book, passphrase)
181
	sites, err := read(book, passphrase)
180
	http.Redirect(w, r, "/book", http.StatusSeeOther)
198
	http.Redirect(w, r, "/book", http.StatusSeeOther)
181
}
199
}
182
200
183
func SignOffHandler(w http.ResponseWriter, r *http.Request) {
201
func SignOutHandler(w http.ResponseWriter, r *http.Request) {
184
	cookieProfile := &http.Cookie{
202
	cookieProfile := &http.Cookie{
185
		Name:   "profile",
203
		Name:   "profile",
186
		MaxAge: -1,
204
		MaxAge: -1,
207
225
208
		c, err = r.Cookie("passphrase")
226
		c, err = r.Cookie("passphrase")
209
		if err == nil {
227
		if err == nil {
210
			passphrase = c.Value
228
			passphrase = string(decodeBase64([]byte(c.Value)))
211
		}
229
		}
230
	} else {
231
		// Set cookies
232
		expire := time.Now().AddDate(0, 0, 1)
233
		cookieProfile := &http.Cookie{
234
			Name:    "profile",
235
			Value:   profile,
236
			Expires: expire,
237
		}
238
		cookiePassphrase := &http.Cookie{
239
			Name:    "passphrase",
240
			Value:   encodeBase64([]byte(passphrase)),
241
			Expires: expire,
242
		}
243
		http.SetCookie(w, cookieProfile)
244
		http.SetCookie(w, cookiePassphrase)
212
	}
245
	}
213
246
214
	if profile == "" || passphrase == "" {
247
	if profile == "" || passphrase == "" {
216
		return
249
		return
217
	}
250
	}
218
251
219
	// Set cookies
220
	//expire := time.Now().AddDate(0, 0, 1)
221
	cookieProfile := &http.Cookie{
222
		Name:  "profile",
223
		Value: profile,
224
		//Path:       "/",
225
		//Domain:     "localhost",
226
		//Expires:    expire,
227
		//RawExpires: expire.Format(time.UnixDate),
228
		//MaxAge:     0,
229
		//Secure:     false,
230
		//HttpOnly:   true,
231
	}
232
	http.SetCookie(w, cookieProfile)
233
	cookiePassphrase := &http.Cookie{
234
		Name:  "passphrase",
235
		Value: passphrase,
236
		//Path:       "/",
237
		//Domain:     "localhost",
238
		//Expires:    expire,
239
		//RawExpires: expire.Format(time.UnixDate),
240
		//MaxAge:     0,
241
		//Secure:     false,
242
		//HttpOnly:   true,
243
	}
244
	http.SetCookie(w, cookiePassphrase)
245
	book := getBookname(profile)
252
	book := getBookname(profile)
246
247
	sites, err := read(book, passphrase)
253
	sites, err := read(book, passphrase)
248
	if err != nil {
254
	if err != nil {
249
		http.Error(w, err.Error(), http.StatusInternalServerError)
255
		//http.Error(w, "Invalid credentials", http.StatusUnauthorized)
256
		http.Redirect(w, r, "/", http.StatusSeeOther)
250
		return
257
		return
251
	}
258
	}
252
	for i, s := range sites {
259
	for i, s := range sites {
256
263
257
	page := Page{
264
	page := Page{
258
		Profile:    profile,
265
		Profile:    profile,
259
		Passphrase: passphrase,
266
		Passphrase: encodeBase64([]byte(passphrase)),
260
		Sites:      sites,
267
		Sites:      sites,
261
	}
268
	}
262
269

+ 1 - 1
main.go

10
	http.HandleFunc("/api/update", ProfileHandler)
10
	http.HandleFunc("/api/update", ProfileHandler)
11
	http.HandleFunc("/api/refresh", RefreshHandler)
11
	http.HandleFunc("/api/refresh", RefreshHandler)
12
	http.HandleFunc("/api/remove", RemoveHandler)
12
	http.HandleFunc("/api/remove", RemoveHandler)
13
	http.HandleFunc("/signout", SignOffHandler)
13
	http.HandleFunc("/signout", SignOutHandler)
14
	http.HandleFunc("/book", BookHandler)
14
	http.HandleFunc("/book", BookHandler)
15
	http.HandleFunc("/", DefaultHandler)
15
	http.HandleFunc("/", DefaultHandler)
16
16

+ 78 - 4
security.go

1
package main
1
package main
2
2
3
import (
4
	"crypto/aes"
5
	"crypto/cipher"
6
	"crypto/rand"
7
	"encoding/base64"
8
	"errors"
9
	"io"
10
	"os"
11
)
12
13
func encodeBase64(data []byte) string {
14
	return base64.StdEncoding.EncodeToString(data)
15
}
16
17
func decodeBase64(data []byte) []byte {
18
	b, _ := base64.StdEncoding.DecodeString(string(data))
19
	return b
20
}
21
22
func getLocalKey() string {
23
	env := os.Getenv("ENIGMA_KEY")
24
	if env == "" {
25
		env = "thebrownfoxjumpedoverthefence"
26
	}
27
28
	return env
29
}
30
31
func getSizedKey(key string) string {
32
	// Get the correct key length
33
	l := len(key)
34
	if l < 16 {
35
		for i := 0; i < 16-l; i++ {
36
			key += "."
37
		}
38
	} else if l < 24 {
39
		for i := 0; i < 24-l; i++ {
40
			key += "."
41
		}
42
	} else if l < 32 {
43
		for i := 0; i < 32-l; i++ {
44
			key += "."
45
		}
46
	} else {
47
		key = key[:32]
48
	}
49
50
	return key
51
}
52
3
// Encrypt the password book
53
// Encrypt the password book
4
func encrypt(clearText, profile, passphrase string) ([]byte, error) {
5
	return nil, nil
54
func encrypt(text, passphrase string) ([]byte, error) {
55
	key := []byte(getSizedKey(passphrase))
56
	block, err := aes.NewCipher(key)
57
	if err != nil {
58
		return nil, err
59
	}
60
	cipherText := make([]byte, aes.BlockSize+len(text))
61
	iv := cipherText[:aes.BlockSize]
62
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
63
		return nil, err
64
	}
65
	encrypter := cipher.NewCFBEncrypter(block, iv)
66
	encrypter.XORKeyStream(cipherText[aes.BlockSize:], []byte(text))
67
	return cipherText, nil
6
}
68
}
7
69
8
// Decrypt the password book
70
// Decrypt the password book
9
func decrypt(encryptedText, profile, passphrase string) ([]byte, error) {
10
	return nil, nil
71
func decrypt(text []byte, passphrase string) ([]byte, error) {
72
	key := []byte(getSizedKey(passphrase))
73
	block, err := aes.NewCipher(key)
74
	if err != nil {
75
		return nil, err
76
	}
77
	if len(text) < aes.BlockSize {
78
		return nil, errors.New("Cipher text too short")
79
	}
80
	iv := text[:aes.BlockSize]
81
	data := text[aes.BlockSize:]
82
	decrypter := cipher.NewCFBDecrypter(block, iv)
83
	decrypter.XORKeyStream(data, data)
84
	return data, nil
11
}
85
}