
Rclone crypt adds client-side encryption to a storage path. Files written through the crypt remote are encrypted before reaching the underlying storage and decrypted when read back through it. Writing directly to that storage path bypasses crypt, so choosing the correct remote is part of the protection.
This guide uses a disposable local directory to test the workflow before introducing a cloud provider. We encrypted five files with Rclone 1.76.0 on Windows, restored them, and repeated recovery with a separately rebuilt configuration. Both restores matched their original SHA-256 file manifests. Provider access, cloud behavior, and Hivenet compatibility were not tested.
In this exercise, vault: is the readable crypt view. The local ciphertext directory holds the stored encrypted files. The crypt documentation explains how the wrapper works. With a cloud backend, the same distinction might be between vault: and storage:bucket/encrypted.
Use a dedicated empty path for encrypted data. Adding a crypt configuration does not convert existing plaintext files in that path. For general copy behavior and transfer checks, see our rclone transfer guide.
Install Rclone using the official instructions and record your version:
rclone version
Create a new working directory with sibling folders named source and ciphertext. Put only disposable regular files in source, including a nested file and an empty file. Leave ciphertext empty. Run every command below from that working directory, keeping configuration files and restore targets outside the source tree.
Use a stable source while recording and copying the files. This same-machine exercise does not protect against losing the machine. Actual backup placement and retention need a separate plan, as covered in our cloud backup guide.
rclone --config ./lab.conf config
In the interactive configuration, create a new remote with these settings. Choose the storage type by name, because menu numbers can change:
| Setting | Value for this exercise |
|---|---|
| Remote name | vault |
| Storage type | crypt |
| Path to encrypt/decrypt | The actual absolute path to your empty ciphertext directory |
| Filename encryption | standard |
| Directory-name encryption | true |
| Crypt password | A new strong secret, retained in your password manager |
| Custom salt / password2 | A separate secret, also retained for recovery |
| Advanced settings | Leave at defaults for this exercise |
A local absolute path is supported, for example C:/rclone-crypt-lab/ciphertext on Windows. Enter your real path, not that example. The two crypt secrets and the name-encryption settings must be reproducible when rebuilding access. A custom salt is not stored with the encrypted files, so retain it alongside the crypt password in your recovery record.
Protect the configuration file as well. Rclone’s obscured password format is reversible; it is not a substitute for encrypting the configuration. After saving the remote, set a separate configuration-file password and verify that the encrypted file can be opened:
rclone --config ./lab.conf config encryption set
rclone --config ./lab.conf config encryption check
The set command protects the configuration, while the check command tests its decryption. Enter passwords at the prompts rather than placing them in command lines. Record which secret protects the files, which is the custom salt, and which unlocks the configuration.
Save this Python 3 helper as verify-files.py in the working directory. It records relative file paths and SHA-256 hashes, then compares a restored tree with that baseline:
import hashlib
import json
import sys
from pathlib import Path
mode, folder, manifest_file = sys.argv[1:]
root = Path(folder)
if mode not in ('record', 'compare') or not root.is_dir():
raise SystemExit('Use record or compare with an existing directory.')
files = {}
for path in sorted(root.rglob('*')):
if path.is_symlink():
raise SystemExit('This example checks regular files, not symlinks.')
if path.is_file():
digest = hashlib.sha256()
with path.open('rb') as stream:
for block in iter(lambda: stream.read(1024 * 1024), b''):
digest.update(block)
files[path.relative_to(root).as_posix()] = digest.hexdigest()
if mode == 'record':
with open(manifest_file, 'x', encoding='utf-8') as stream:
json.dump(files, stream, indent=2)
print('Recorded', len(files), 'files')
else:
expected = json.loads(Path(manifest_file).read_text(encoding='utf-8'))
if files != expected:
raise SystemExit('FAIL: file paths or SHA-256 hashes differ.')
print('PASS:', len(files), 'files match')
python verify-files.py record source baseline.json
Use python3 if that is your Python command. The helper refuses to overwrite an existing baseline. It checks regular-file bytes and paths, including missing or extra files; it does not check empty directories, timestamps, permissions, or application consistency. Keep the source unchanged through the copy.
rclone --config ./lab.conf copy ./source vault: --dry-run --verbose
rclone --config ./lab.conf copy ./source vault: --verbose
Run these commands separately and inspect the preview first. The copy command copies the directory’s contents. It can replace changed destination files but does not delete extra destination files. The fresh destination in this exercise avoids existing-file decisions. A dry run previews operations without copying the data.
Inspect both views with these read-only listings:
rclone --config ./lab.conf lsf vault: --recursive
rclone --config ./lab.conf lsf ./ciphertext --recursive
The crypt listing should show your readable names. The direct listing shows the stored encrypted names. This is a useful configuration check, not a cryptographic audit. Do not upload plaintext directly into the ciphertext directory or mix it with the crypt-managed files.
Check the encrypted copy against its source:
rclone --config ./lab.conf cryptcheck ./source vault:
cryptcheck requires a checksum supported by the underlying backend. It uses each encrypted file’s nonce to compare the corresponding encrypted content. Read the result and exit status. If the intended cloud backend cannot support that check, a full decrypt-and-compare exercise still matters.
Use a target named restore-check that does not already exist. Inspect the restore preview before running the real copy:
rclone --config ./lab.conf copy vault: ./restore-check --dry-run --verbose
rclone --config ./lab.conf copy vault: ./restore-check --verbose
python verify-files.py compare restore-check baseline.json
A passing comparison prints PASS and the file count. A missing, extra, or changed file fails the comparison. A readable listing or a successful transfer command alone does not establish that the complete expected dataset was recovered.
Keep the original configuration safe, but create a separate file for the recovery test:
rclone --config ./recovery.conf config
Create a crypt remote named recovery pointing to the same absolute ciphertext path. Enter the original crypt password, original custom salt, and the same filename and directory-name settings. Do not generate new crypt secrets. The remote’s display name can differ.
Protect the rebuilt configuration, then restore into another new target. All these commands explicitly use recovery.conf:
rclone --config ./recovery.conf config encryption set
rclone --config ./recovery.conf config encryption check
rclone --config ./recovery.conf copy recovery: ./restore-rebuilt --verbose
python verify-files.py compare restore-rebuilt baseline.json
rclone --config ./recovery.conf cryptcheck ./source recovery:
In our local test, we renamed the original configuration before this second restore. Both five-file restores matched the recorded hashes, and both crypt checks passed. We also tried an incorrect salt: Rclone skipped unreadable names and returned exit code zero, but the restored dataset did not match the baseline. That result is why an explicit file comparison belongs in the recovery test.
A separate copy of the ciphertext with one modified byte failed to restore correctly and returned an error. The original encrypted files stayed unchanged. These checks cover the tested local files, not every corruption case, metadata type, or cloud failure. Our recoverability testing guide helps extend the exercise to a real recovery requirement.
Before using a provider, validate the underlying remote and choose a dedicated encrypted path. Repeat the copy and restore checks with representative names, file sizes, and the intended recovery identity. The local backend used here does not exercise provider path limits, authorization, network retries, or cloud costs.
Encryption leaves some information visible, including directory structure, modification times, and information about file lengths. It also does not provide version history or prevent an authorized account from deleting ciphertext. Keep recovery copies and retention decisions separate from the encryption settings.
Changing the password that unlocks the configuration does not rotate the file-encryption key. Changing the crypt password or custom salt does not re-encrypt existing content either. Plan a verified migration to a new encrypted destination when data keys need to change, and preserve recovery access until that migration is checked.
For scheduled jobs, use the documented configuration-unlock mechanisms and a protected secret source. Review existing RCLONE_* environment variables, because they can affect settings even when a configuration file is specified. Retain the configuration, crypt secrets, backend-access details, and a tested recovery procedure independently of the machine being protected.
Pick one AI, compute, or storage workload and see the difference for yourself. Spin it up in minutes, or let our team map your fastest path to production.