8
8
"crypto/sha512"
9
9
"errors"
10
10
"fmt"
11
+ chacha "golang.org/x/crypto/chacha20poly1305"
11
12
"golang.org/x/crypto/pbkdf2"
12
13
"io"
13
14
"math/big"
@@ -96,7 +97,7 @@ func isFileEncrypted(encDbPath string) (error, bool) {
96
97
}
97
98
98
99
// Encrypt the database path using AES
99
- func encryptFile (dbPath string , password string ) error {
100
+ func encryptFileAES (dbPath string , password string ) error {
100
101
101
102
var err error
102
103
var key []byte
@@ -136,10 +137,12 @@ func encryptFile(dbPath string, password string) error {
136
137
return err
137
138
}
138
139
139
- err , nonce = generateRandomBytes (aesGCM .NonceSize ())
140
+ nonceSize := aesGCM .NonceSize ()
141
+ // fmt.Printf("%d\n", nonceSize)
142
+ err , nonce = generateRandomBytes (nonceSize )
140
143
141
144
if err != nil {
142
- fmt .Printf ("Error - Init vector generation failed -\" %s\" \n " , err )
145
+ fmt .Printf ("Error - Nonce generation failed -\" %s\" \n " , err )
143
146
return err
144
147
}
145
148
@@ -159,9 +162,9 @@ func encryptFile(dbPath string, password string) error {
159
162
160
163
encDbPath = dbPath + ".varuh"
161
164
162
- err = os .WriteFile (encDbPath , encText , 0644 )
165
+ err = os .WriteFile (encDbPath , encText , 0600 )
163
166
if err == nil {
164
- err = os .WriteFile (dbPath , encText , 0644 )
167
+ err = os .WriteFile (dbPath , encText , 0600 )
165
168
if err == nil {
166
169
// Remove backup
167
170
os .Remove (encDbPath )
@@ -174,8 +177,8 @@ func encryptFile(dbPath string, password string) error {
174
177
return err
175
178
}
176
179
177
- // Decrypt an already encrypted database file using given password
178
- func decryptFile (encDbPath string , password string ) error {
180
+ // Decrypt an already encrypted database file using given password using AES
181
+ func decryptFileAES (encDbPath string , password string ) error {
179
182
180
183
var encText []byte
181
184
var cipherText []byte
@@ -246,7 +249,155 @@ func decryptFile(encDbPath string, password string) error {
246
249
return err
247
250
}
248
251
249
- err = rewriteBaseFile (encDbPath , plainText , 0600 )
252
+ err , origFile = rewriteBaseFile (encDbPath , plainText , 0600 )
253
+
254
+ if err != nil {
255
+ fmt .Printf ("Error writing decrypted data to %s - \" %s\" \n " , origFile , err .Error ())
256
+ }
257
+
258
+ // fmt.Printf("%s\n", string(plainText))
259
+ return err
260
+ }
261
+
262
+ // Encrypt a file using XChaCha20-Poly1305 cipher
263
+ func encryptFileXChachaPoly (dbPath string , password string ) error {
264
+
265
+ var err error
266
+ var key []byte
267
+ var nonce []byte
268
+ var salt []byte
269
+ var plainText []byte
270
+ var cipherText []byte
271
+ var magicBytes []byte
272
+ var encText []byte
273
+ var encDbPath string
274
+ var hmacHash []byte
275
+
276
+ plainText , err = os .ReadFile (dbPath )
277
+ if err != nil {
278
+ fmt .Printf ("Error - Can't read database -\" %s\" \n " , err )
279
+ return err
280
+ }
281
+
282
+ err , key , salt = generateKey (password , nil )
283
+
284
+ if err != nil {
285
+ fmt .Printf ("Error - Key derivation failed -\" %s\" \n " , err )
286
+ return err
287
+ }
288
+
289
+ aead , err := chacha .NewX (key )
290
+
291
+ if err != nil {
292
+ fmt .Printf ("Error - AEAD creation failed - \" %s\" \n " , err )
293
+ return err
294
+ }
295
+
296
+ nonce = make ([]byte , aead .NonceSize (), aead .NonceSize ()+ len (plainText )+ aead .Overhead ())
297
+ if _ , err = crand .Read (nonce ); err != nil {
298
+ fmt .Printf ("Error - Nonce generation failed -\" %s\" \n " , err )
299
+ return err
300
+ }
301
+
302
+ magicBytes = []byte (fmt .Sprintf ("%x" , MAGIC_HEADER ))
303
+ cipherText = aead .Seal (nonce , nonce , plainText , nil )
304
+
305
+ // Calculate hmac signature and write it
306
+ hCipher := hmac .New (sha512 .New , key )
307
+ hCipher .Write (cipherText )
308
+
309
+ hmacHash = hCipher .Sum (nil )
310
+
311
+ // No need for salt in chacha
312
+ encText = append (magicBytes , salt ... )
313
+ encText = append (encText , hmacHash ... )
314
+ encText = append (encText , cipherText ... )
315
+
316
+ encDbPath = dbPath + ".varuh"
317
+
318
+ err = os .WriteFile (encDbPath , encText , 0600 )
319
+ if err == nil {
320
+ err = os .WriteFile (dbPath , encText , 0600 )
321
+ if err == nil {
322
+ // Remove backup
323
+ os .Remove (encDbPath )
324
+ } else {
325
+ fmt .Printf ("Error writing encrypted database - \" %s\" \n " , err .Error ())
326
+ }
327
+ }
328
+ // fmt.Printf("%x\n", cipherText)
329
+
330
+ return err
331
+ }
332
+
333
+ // Decrypt an already encrypted database file using given password using AES
334
+ func decryptFileXChachaPoly (encDbPath string , password string ) error {
335
+
336
+ var encText []byte
337
+ var cipherText []byte
338
+ var plainText []byte
339
+ var salt []byte
340
+ var key []byte
341
+ var nonce []byte
342
+ var hmacHash []byte
343
+ var hmacSig []byte
344
+ var origFile string
345
+
346
+ var err error
347
+
348
+ encText , err = os .ReadFile (encDbPath )
349
+ if err != nil {
350
+ fmt .Printf ("Error - Can't read database -\" %s\" \n " , err )
351
+ return err
352
+ }
353
+
354
+ encText = encText [unsafe .Sizeof (MAGIC_HEADER ):]
355
+ // Read the old salt
356
+ salt , encText = encText [:SALT_SIZE ], encText [SALT_SIZE :]
357
+ // Read the hmac hash checksum
358
+ hmacHash , encText = encText [:HMAC_SHA512_SIZE ], encText [HMAC_SHA512_SIZE :]
359
+
360
+ err , key , _ = generateKey (password , & salt )
361
+
362
+ if err != nil {
363
+ fmt .Printf ("Error - Key derivation failed -\" %s\" \n " , err )
364
+ return err
365
+ }
366
+
367
+ // verify the hmac
368
+ // Calculate hmac signature and write it
369
+ hCipher := hmac .New (sha512 .New , key )
370
+ hCipher .Write (encText )
371
+
372
+ hmacSig = hCipher .Sum (nil )
373
+
374
+ // Compare
375
+ if ! hmac .Equal (hmacSig , hmacHash ) {
376
+ fmt .Println ("Invalid password or tampered data. Aborted" )
377
+ return errors .New ("signature check failed" )
378
+ }
379
+ // fmt.Printf("\nsalt: %x\n", salt)
380
+ // fmt.Printf("key: %x\n", key)
381
+
382
+ aead , err := chacha .NewX (key )
383
+ if err != nil {
384
+ fmt .Printf ("Error - AEAD creation failed - \" %s\" \n " , err )
385
+ return err
386
+ }
387
+
388
+ nonceSize := aead .NonceSize ()
389
+
390
+ nonce , cipherText = encText [:nonceSize ], encText [nonceSize :]
391
+ // fmt.Printf("nonce: %x\n", nonce)
392
+ plainText , err = aead .Open (nil , nonce , cipherText , nil )
393
+
394
+ if err != nil {
395
+ fmt .Printf ("Error - Decryption failed - \" %s\" \n " , err )
396
+ return err
397
+ }
398
+
399
+ // err = os.WriteFile("test.sqlite3", plainText, 0600)
400
+ err , origFile = rewriteBaseFile (encDbPath , plainText , 0600 )
250
401
251
402
if err != nil {
252
403
fmt .Printf ("Error writing decrypted data to %s - \" %s\" \n " , origFile , err .Error ())
0 commit comments