From 08f82ee40867f605ca6994db6dc32218d7b85cbc Mon Sep 17 00:00:00 2001 From: Andrey Andreyevich Bienkowski Date: Mon, 11 Apr 2022 09:21:07 +0000 Subject: [PATCH] Argon2: documentation and changelog (#6560) docs: borg key change-algorithm docs: borg init --key-algorithm docs: "this is not a borg repo" can be due to argon2 and old borg --- docs/changes.rst | 2 ++ docs/faq.rst | 9 ++++++++ docs/usage/key.rst | 6 ++++-- setup_docs.py | 3 +++ src/borg/archiver.py | 51 ++++++++++++++++++++++++++++++++++++++------ 5 files changed, 63 insertions(+), 8 deletions(-) diff --git a/docs/changes.rst b/docs/changes.rst index 5a84d85ab..3c8eef910 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -235,6 +235,8 @@ New features: Solves the potential AES-CTR mode counter management issues of the legacy crypto. - init: --key-algorithm=argon2 (new default KDF, older pbkdf2 also still available) borg key change-passphrase / change-location keeps the key algorithm unchanged. +- key change-algorithm: to upgrade existing keys to argon2 or downgrade to pbkdf2. + We recommend you to upgrade unless you have to keep the key compatible with older versions of borg. - key change-location: usable for repokey <-> keyfile location change - benchmark cpu: display benchmarks of cpu bound stuff - export-tar: new --tar-format=PAX (default: GNU) diff --git a/docs/faq.rst b/docs/faq.rst index bbf81f15b..cc464aa1d 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -745,6 +745,15 @@ the nonce is deleted or if you suspect it may have been tampered with. See :ref: Common issues ############# +/path/to/repo is not a valid repository. Check repo config. +----------------------------------------------------------- + +There can be many causes of this error. E.g. you have incorrectly specified the repository path. + +You will also get this error if you try to access a repository with a key that uses the argon2 key algorithm using an old version of borg. +We recommend upgrading to the latest stable version and trying again. We are sorry. We should have thought about forward +compatibility and implemented a more helpful error message. + Why does Borg extract hang after some time? ------------------------------------------- diff --git a/docs/usage/key.rst b/docs/usage/key.rst index d923fd2dc..f175ac1d7 100644 --- a/docs/usage/key.rst +++ b/docs/usage/key.rst @@ -1,9 +1,11 @@ +.. include:: key_change-location.rst.inc + +.. include:: key_change-algorithm.rst.inc + .. _borg-change-passphrase: .. include:: key_change-passphrase.rst.inc -.. include:: key_change-location.rst.inc - Examples ~~~~~~~~ :: diff --git a/setup_docs.py b/setup_docs.py index 9513604bb..056c23213 100644 --- a/setup_docs.py +++ b/setup_docs.py @@ -302,6 +302,8 @@ class build_man(Command): 'with-lock': 'lock', 'key_change-passphrase': 'key', + 'key_change-location': 'key', + 'key_change-algorithm': 'key', 'key_export': 'key', 'key_import': 'key', 'key_migrate-to-repokey': 'key', @@ -310,6 +312,7 @@ class build_man(Command): 'import-tar': 'tar', 'benchmark_crud': 'benchmark', + 'benchmark_cpu': 'benchmark', 'umount': 'mount', } diff --git a/src/borg/archiver.py b/src/borg/archiver.py index d2a745621..81677b04a 100644 --- a/src/borg/archiver.py +++ b/src/borg/archiver.py @@ -4247,10 +4247,11 @@ class Archiver: 1. Ask you to come up with a passphrase. 2. Create a borg key (which contains some random secrets. See :ref:`key_files`). - 3. Encrypt the key with your passphrase. - 4. Store the encrypted borg key inside the repository directory (in the repo config). + 3. Derive a "key encryption key" from your passphrase + 4. Encrypt and sign the key with the key encryption key + 5. Store the encrypted borg key inside the repository directory (in the repo config). This is why it is essential to use a secure passphrase. - 5. Encrypt and sign your backups to prevent anyone from reading or forging them unless they + 6. Encrypt and sign your backups to prevent anyone from reading or forging them unless they have the key and know the passphrase. Make sure to keep a backup of your key **outside** the repository - do not lock yourself out by "leaving your keys inside your car" (see :ref:`borg_key_export`). @@ -4258,7 +4259,7 @@ class Archiver: never sees your passphrase, your unencrypted key or your unencrypted files. Chunking and id generation are also based on your key to improve your privacy. - 6. Use the key when extracting files to decrypt them and to verify that the contents of + 7. Use the key when extracting files to decrypt them and to verify that the contents of the backups have not been accidentally or maliciously altered. Picking a passphrase @@ -4329,6 +4330,25 @@ class Archiver: If you do **not** want to encrypt the contents of your backups, but still want to detect malicious tampering use an `authenticated` mode. It's like `repokey` minus encryption. + + Key derivation functions + ++++++++++++++++++++++++ + + - ``--key-algorithm argon2`` is the default and is recommended. + The key encryption key is derived from your passphrase via argon2-id. + Argon2 is considered more modern and secure than pbkdf2. + + - You can use ``--key-algorithm pbkdf2`` if you want to access your repo via old versions of borg. + + Our implementation of argon2-based key algorithm follows the cryptographic best practices: + + - It derives two separate keys from your passphrase: one to encrypt your key and another one + to sign it. ``--key-algorithm pbkdf2`` uses the same key for both. + + - It uses encrypt-then-mac instead of encrypt-and-mac used by ``--key-algorithm pbkdf2`` + + Neither is inherently linked to the key derivation function, but since we were going + to break backwards compatibility anyway we took the opportunity to fix all 3 issues at once. """) subparser = subparsers.add_parser('init', parents=[common_parser], add_help=False, description=self.do_init.__doc__, epilog=init_epilog, @@ -4351,7 +4371,8 @@ class Archiver: help='Set storage quota of the new repository (e.g. 5G, 1.5T). Default: no quota.') subparser.add_argument('--make-parent-dirs', dest='make_parent_dirs', action='store_true', help='create the parent directories of the repository directory, if they are missing.') - subparser.add_argument('--key-algorithm', dest='key_algorithm', default='argon2', choices=list(KEY_ALGORITHMS)) + subparser.add_argument('--key-algorithm', dest='key_algorithm', default='argon2', choices=list(KEY_ALGORITHMS), + help='the algorithm we use to derive a key encryption key from your passphrase. Default: argon2') # borg key subparser = subparsers.add_parser('key', parents=[mid_common_parser], add_help=False, @@ -4485,15 +4506,33 @@ class Archiver: change_algorithm_epilog = process_epilog(""" Change the algorithm we use to encrypt and authenticate the borg key. + Important: In a `repokey` mode (e.g. repokey-blake2) all users share the same key. + In this mode upgrading to `argon2` will make it impossible to access the repo for users who use an old version of borg. + We recommend upgrading to the latest stable version. + + Important: In a `keyfile` mode (e.g. keyfile-blake2) each user has their own key (in ``~/.config/borg/keys``). + In this mode this command will only change the key used by the current user. + If you want to upgrade to `argon2` to strengthen security, you will have to upgrade each user's key individually. + Your repository is encrypted and authenticated with a key that is randomly generated by ``borg init``. The key is encrypted and authenticated with your passphrase. We currently support two choices: + 1. argon2 - recommended. This algorithm is used by default when initialising a new repository. The key encryption key is derived from your passphrase via argon2-id. Argon2 is considered more modern and secure than pbkdf2. - 1. pbkdf2 - the legacy algorithm. Use this if you want to access your repo via old versions of borg. + 2. pbkdf2 - the legacy algorithm. Use this if you want to access your repo via old versions of borg. The key encryption key is derived from your passphrase via PBKDF2-HMAC-SHA256. + + Examples:: + + # Upgrade an existing key to argon2 + borg key change-algorithm /path/to/repo argon2 + # Downgrade to pbkdf2 - use this if upgrading borg is not an option + borg key change-algorithm /path/to/repo pbkdf2 + + """) subparser = key_parsers.add_parser('change-algorithm', parents=[common_parser], add_help=False, description=self.do_change_algorithm.__doc__,