How secure is duplicacy?

Same machine. Same repository. Same storage.

Thank you!!

I will need to study this and try to apply to my case because i actually use Duplicacy Web Edition in a container and this seems a little tricky.

Ah, yeah. I couldn’t begin to tell you how you might do it there. I’m a CLI Linux user with a ton of custom wrapper scripts to accomplish my workflow.

This is my doubt. Iirc when initializing a storage with Duplicacy CLI or Web Edition the user needs to input the app key for the B2 bucket.

So i actually understand how you import and decrypt the key. But how you use the prune command with a B2 app key that is different from the one that was used to initiate the storage?

The next step in my script (which I didn’t show) was in essence to run the “duplicacy prune” command (with a bunch of parameters). Since the B2 ID and KEY are now stored in environment variables, those values take precedence over the values stored in the preferences or keyrings. So it just works.

1 Like

I could maybe write a script that asks to enter the keys manually (copy-pasting from a secure password vault) and stores it in the env variables and then export them?

I’ve been using this Python wrapper script with the Web UI on a QNAP NAS to log notifications and to ping healthchecks.io. I successfully experimented with using the following code to set the B2 key environment variables for the CLI:

#!/usr/bin/env python
'''
Decrypts and exports B2 encryption key, prune key ID, and prune key.

'''
from __future__ import print_function
import os
import os.path
from subprocess import *
import getpass
import re

pgp = """-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.7 (GNU/Linux)

<<< encrypted key deleted >>>
-----END PGP MESSAGE-----"""

passphrase = getpass.getpass(prompt='Passphrase: ')
p1 = Popen(['echo', pgp], stdout=PIPE)
p2 = Popen(['gpg', '--passphrase', passphrase, '--quiet', '--decrypt'], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
creds = p2.communicate()[0]

for cred in creds.split():
	m = re.match(r'(\w+)=(\S+)', cred)
	if m:
		var, val = m.group(1, 2)
		os.environ[var] = val
		print('export {}={}'.format(var, os.environ[var]))
		
call('env')

I’ve not implemented this because I prefer fully automated backups, so I’d need to store the cleartext passphrase somewhere. There might still be some value in doing this, since generic ransomware would be less likely to target such a customized setup (“security by obscurity”).

1 Like

Maybe duplicacy can integrate with keyring to store the files in encrypted form and prompts for passwd for decryption to clear text?