Wie kann ein privater PyNaCl-Schlüssel (libsodium) in Python sicher auf der Festplatte gespeichert werden (einfache DatePython

Python-Programme
Anonymous
 Wie kann ein privater PyNaCl-Schlüssel (libsodium) in Python sicher auf der Festplatte gespeichert werden (einfache Date

Post by Anonymous »

Ich baue einen kleinen Python-Client für einen FastAPI-Dienst, der einmalig verschlüsselte Nachrichten sendet. Schlüssel müssen auf dem Client verbleiben (niemals an den Server gesendet oder dort gespeichert).
Env/Libraries

[*]Python 3.11
[*][PyNaCl] für />Behalten Sie ein langlebiges PyNaCl-Schlüsselpaar zwischen den Läufen bei. Ich möchte, dass der private Schlüssel im Ruhezustand auf der Festplatte verschlüsselt und erst entschlüsselt wird, nachdem der Benutzer eine Passphrase eingegeben hat (oder alternativ den Schlüsselbund des Betriebssystems verwenden, wenn dies als Best Practice angesehen wird).
Was ich versucht habe
  • Den rohen privaten 32-Byte-Schlüssel in eine Datei schreiben → einfach, aber im Ruhezustand offensichtlich nicht sicher.
  • Verwendung von Kryptografie zum Ableiten eines Schlüssels aus einem Passphrase (Scrypt) und verschlüsseln Sie den privaten Schlüssel mit AES-GCM, bevor Sie ihn auf die Festplatte schreiben. Das funktioniert, aber ich bin mir über die empfohlenen Parameter/Muster nicht sicher.
  • Verwenden des Schlüsselringpakets zum Speichern des privaten Schlüssels im Anmeldeinformationsspeicher des Betriebssystems (Windows DPAPI / macOS-Schlüsselbund / Secret Service). Dadurch werden Passphrasen vermieden, aber ich bin mir nicht sicher, was Portabilität und Sicherung/Wiederherstellung betrifft.
    Minimale Repro (Skizze)
    Python 3.11
    pip install pynacl cryptography

    Code: Select all

    from nacl.public import PrivateKey
    from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
    from cryptography.hazmat.primitives.ciphers.aead import AESGCM
    from cryptography.hazmat.primitives import serialization
    from cryptography.hazmat.backends import default_backend
    import os, json, base64
    
    # 1) Generate
    sk = PrivateKey.generate()
    pk = sk.public_key
    sk_bytes = bytes(sk)               # 32 bytes
    pk_bytes = bytes(pk)               # 32 bytes (saved in clear is fine)
    
    # 2) Derive wrap key from passphrase
    def derive_key(passphrase: str, salt: bytes) -> bytes:
    kdf = Scrypt(salt=salt, length=32, n=2**15, r=8, p=1,
    backend=default_backend())
    return kdf.derive(passphrase.encode("utf-8"))
    
    3) Geheimen Schlüssel mit AES-GCM verschlüsseln und speichern (salt, nonce, ct)
    def store_key(sk_bytes: bytes, passphrase: str, path="keystore.json"):
    salt = os.urandom(16)
    nonce = os.urandom(12)
    aead_key = derive_key(passphrase, salt)
    ct = AESGCM(aead_key).encrypt(nonce, sk_bytes, Associated_data=None)
    data = {
    "salt": base64.b64encode(salt).decode(),
    "nonce": base64.b64encode(nonce).decode(),
    "ct": base64.b64encode(ct).decode(),
    "pub": base64.b64encode(pk_bytes).decode(),
    }
    mit open(path, "w") as f:
    json.dump(data, f)
    4) Load + decrypt
    def load_key(passphrase: str, path="keystore.json") -> Bytes:
    data = json.load(open(path))
    salt = base64.b64decode(data["salt"])
    nonce = base64.b64decode(data["nonce"])
    ct = base64.b64decode(data["ct"])
    aead_key = derive_key(passphrase, salt)
    sk_bytes = AESGCM(aead_key).decrypt(nonce, ct, Associated_data=None)
    return sk_bytes
    Verwendung:
    store_key(sk_bytes, "my passphrase")
    recovered = load_key("my passphrase")
    assert protected == sk_bytes
Fragen
  • Ist „Von Verschlüsselung abgeleiteter Schlüssel + AES-GCM-Verpackung, dann JSON in einer Datei speichern“ ein sinnvolles Muster für die clientseitige Schlüsselpersistenz mit PyNaCl? Irgendwelche empfohlenen Scrypt-Parameter für Desktops im Jahr 2025?
  • Würden Sie stattdessen die Verwendung des Betriebssystem-Schlüsselbunds per Schlüsselbund empfehlen (und wenn ja, wie kann man 32 Rohbytes sicher und portabel speichern)?
  • Gibt es Fallstricke mit X25519-Schlüsseln in PyNaCl bei dieser Serialisierung/Deserialisierung?
    Einschränkungen
    Ich kann keine Geheimnisse auf dem Server speichern. Es ist in Ordnung, den Benutzer beim Start nach einer Passphrase zu fragen; keine UI-Frameworks erforderlich.
    Erwartet:
    Anleitung oder Beispielcode, der den empfohlenen Ansatz (mit Passphrase umschlossene Datei vs. Betriebssystem-Schlüsselbund) und Parameteroptionen (Verschlüsselungskosten, AES-GCM-Nonce-Handhabung usw.) zeigt.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post