Privacy Tools Guide

Implement a dead man’s switch using multiple independent trustees by dividing your recovery credentials into Shamir shares, storing encrypted shares with each trustee, and using a time-based verification service (like Dead Man’s Switch or similar platforms). Trustees receive credentials only if you fail to check in monthly, and each trustee independently holds an incomplete share that requires at least 3 of 5 trustees to reconstruct your passwords. This decentralized approach eliminates any single point of failure for your digital legacy.

Understanding the Architecture

The core concept involves distributing cryptographic shares among several trustees, where a threshold number of trustees must cooperate to reconstruct the credential. This threshold cryptography approach, often implemented using Shamir’s Secret Sharing, ensures that no single trustee can access your credentials independently.

A typical setup might involve five trustees with a threshold of three. This means any three of the five trustees must come together to reconstruct the secret. Even if two trustees become unavailable or malicious, the system still functions.

The “dead man’s switch” element adds a time-based check-in mechanism. If you fail to confirm your presence within the designated period, the system triggers the release process to your designated trustees.

Implementing Shamir’s Secret Sharing

Shamir’s Secret Sharing divides a secret into multiple shares, where a configurable threshold determines how many shares are required to reconstruct the original secret. Here’s a Python implementation using the ssss library or cryptography:

from cryptography.fernet import Fernet
from secrets import token_bytes
import hashlib

def generate_shares(secret: str, num_shares: int, threshold: int) -> list[str]:
    """
    Generate shares using a simple XOR-based approach for demonstration.
    For production, use proper Shamir's Secret Sharing (e.g., python-ssss library).
    """
    if threshold > num_shares:
        raise ValueError("Threshold cannot exceed number of shares")

    # Pad secret to multiple of threshold for even distribution
    secret_bytes = secret.encode()
    padding = (threshold - len(secret_bytes) % threshold) % threshold
    secret_bytes += b'\x00' * padding

    # Split into chunks
    chunks = [secret_bytes[i:i+threshold]
              for i in range(0, len(secret_bytes), threshold)]

    shares = []
    for i in range(num_shares):
        share = bytes(chunk[i] if i < len(chunk) else 0
                     for chunk in chunks)
        shares.append(share.hex())

    return shares

# Example usage
secret = "your-master-recovery-key-here"
shares = generate_shares(secret, num_shares=5, threshold=3)
print(f"Generated {len(shares)} shares, need {3} to reconstruct")

For production systems, use the ssss library which implements proper polynomial-based secret sharing:

pip install python-ssss
import ssss

# Generate 5 shares with threshold of 3
shares = ssss.generate_shares("your-secret-key", 5, 3)
for i, share in enumerate(shares):
    print(f"Share {i+1}: {share}")

# Reconstruct from any 3 shares
reconstructed = ssss.combine_shares(shares[:3])
print(f"Reconstructed: {reconstructed}")

Building the Check-In Mechanism

The dead man’s switch requires a reliable check-in system. This example uses a simple file-based timestamp that you update regularly:

import json
import os
import time
from pathlib import Path

class DeadManSwitch:
    def __init__(self, config_path: str = "~/.deadmanswitch/config.json"):
        self.config_path = Path(config_path).expanduser()
        self.config = self._load_config()

    def _load_config(self) -> dict:
        if self.config_path.exists():
            with open(self.config_path) as f:
                return json.load(f)
        return {
            "checkin_interval_seconds": 86400 * 7,  # 7 days
            "last_checkin": None,
            "trustees": [],
            "threshold": 3
        }

    def checkin(self):
        """Update the last check-in timestamp."""
        self.config["last_checkin"] = time.time()
        self._save_config()
        print(f"Check-in successful. Next due in {self.config['checkin_interval_seconds']/86400} days.")

    def _save_config(self):
        self.config_path.parent.mkdir(parents=True, exist_ok=True)
        with open(self.config_path, 'w') as f:
            json.dump(self.config, f, indent=2)

    def is_expired(self) -> bool:
        """Check if the dead man's switch has expired."""
        if self.config["last_checkin"] is None:
            return True

        elapsed = time.time() - self.config["last_checkin"]
        return elapsed > self.config["checkin_interval_seconds"]

    def trigger_if_expired(self):
        """Trigger the release mechanism if check-in has expired."""
        if self.is_expired():
            print("DEAD MAN'S SWITCH TRIGGERED - notifying trustees")
            self._notify_trustees()
            return True
        return False

    def _notify_trustees(self):
        """Send notification to trustees (implement your notification logic)."""
        for trustee in self.config["trustees"]:
            print(f"Notifying trustee: {trustee['name']} at {trustee['contact']}")

# Usage
switch = DeadManSwitch()
switch.checkin()  # Call this regularly (automate with cron)

Automating the Check-In

For a system, automate the check-in process using cron jobs or systemd timers. Create a simple script that runs daily:

#!/bin/bash
# ~/.deadmanswitch/checkin.sh

PYTHONPATH=/path/to/your/scripts python3 -c "
from deadman_switch import DeadManSwitch
switch = DeadManSwitch()
if switch.is_expired():
    switch.trigger_if_expired()
else:
    switch.checkin()
"

Add to your crontab:

0 9 * * * ~/.deadmanswitch/checkin.sh >> ~/.deadmanswitch/log.txt 2>&1

Distributing Shares to Trustees

Once you’ve generated your credential shares, distribute them to your trustees through separate, secure channels. Avoid sending all shares through the same communication channel.

def create_trustee_package(trustee_name: str, share: str, instructions: str) -> dict:
    """Create a package to give to a trustee."""
    return {
        "trustee": trustee_name,
        "share_id": hashlib.sha256(share.encode()).hexdigest()[:8],
        "share": share,  # In practice, encrypt this with trustee's public key
        "instructions": instructions,
        "threshold_required": 3,
        "total_trustees": 5
    }

# Example instructions template
instructions = """
You have been designated as a credential recovery trustee.

If you receive notification that the dead man's switch has been triggered:
1. Wait until you have been contacted by at least {threshold} other trustees
2. Verify the trigger is legitimate through your established communication channel
3. Use your share to help reconstruct the master key
4. Follow the recovery instructions provided separately

Do NOT share your share with anyone except during the organized recovery process.
"""

Security Considerations

When implementing this system, several security factors require attention:

Trustee selection matters significantly. Choose trustees who are geographically distributed and unlikely to experience the same incapacitating event. Consider a mix of technical and non-technical trustees, and ensure at least some understand cryptographic fundamentals.

Communication channels should be separate from where you store the shares. If your email is compromised, attackers shouldn’t be able to reconstruct the full picture from intercepted messages.

Regular testing proves the system works when needed. Periodically verify that trustees still have their shares and understand their responsibilities.

Jurisdictional concerns affect legal enforceability. Different countries have varying laws about digital inheritance. Consult legal counsel if your threat model includes legal challenges to your inheritance arrangements.

Advanced: Encrypted Trustee Communication

For enhanced security, implement encrypted communication between trustees using a purpose-built key exchange:

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

def generate_trustee_keys():
    """Generate RSA keypair for trustee."""
    private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
    public_key = private_key.public_key()
    return private_key, public_key

def encrypt_share_for_trustee(share: str, public_key) -> bytes:
    """Encrypt a share with trustee's public key."""
    aes_key = token_bytes(32)  # Generate random AES key
    aesgcm = AESGCM(aes_key)
    nonce = token_bytes(12)
    encrypted_share = aesgcm.encrypt(nonce, share.encode(), None)

    # Encrypt AES key with RSA public key
    encrypted_key = public_key.encrypt(
        aes_key,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

    return nonce + encrypted_share + encrypted_key

Getting Started

Begin by identifying what credentials need this protection—typically master password recovery keys, encryption keys for cold storage, or access credentials for critical systems. Generate your shares using proper cryptographic libraries, then carefully distribute them to trustees you’ve personally vetted.

Set up your automated check-in system immediately, and test the full flow at least once before relying on it. Document the recovery process somewhere secure (separate from the shares themselves) so trustees know what to do when the time comes.

The peace of mind this system provides comes from knowing that your digital assets remain accessible to your chosen trustees if something happens to you, without creating a single point of failure that could compromise your security.

Built by theluckystrike — More at zovo.one