Technical architecture, cryptographic primitives, threat model, and security properties of Sifero Cloud.
Техническая архитектура, криптографические примитивы, модель угроз и свойства безопасности Sifero Cloud.
Technische Architektur, kryptografische Primitive, Bedrohungsmodell und Sicherheitseigenschaften von Sifero Cloud.
Arquitectura técnica, primitivas criptográficas, modelo de amenazas y propiedades de seguridad de Sifero Cloud.
Arquitetura técnica, primitivas criptográficas, modelo de ameaças e propriedades de segurança do Sifero Cloud.
Sifero Cloud is a Zero-Knowledge encrypted cloud storage service. All encryption and decryption happens exclusively in the user's browser using the Web Crypto API. The server stores only encrypted blobs and cannot decrypt any user data.
Sifero Cloud - это сервис облачного хранилища с шифрованием Zero-Knowledge. Все шифрование и расшифровка происходят исключительно в браузере пользователя с использованием Web Crypto API. Сервер хранит только зашифрованные данные и не может расшифровать данные пользователей.
Sifero Cloud ist ein Zero-Knowledge-verschlüsselter Cloud-Speicher-Dienst. Alle Ver- und Entschlusselungen finden ausschließlich im Browser des Benutzers über die Web Crypto API statt. Der Server speichert nur verschlüsselte Blobs und kann keine Benutzerdaten entschlüsseln.
Sifero Cloud es un servicio de almacenamiento en la nube con cifrado Zero-Knowledge. Todo el cifrado y descifrado ocurre exclusivamente en el navegador del usuario utilizando la Web Crypto API. El servidor almacena solo blobs cifrados y no puede descifrar ningún dato del usuario.
Sifero Cloud e um servico de armazenamento em nuvem com criptografia Zero-Knowledge. Toda a criptografia e descriptografia ocorre exclusivamente no navegador do usuario usando a Web Crypto API. O servidor armazena apenas blobs criptografados e nao pode descriptografar nenhum dado do usuario.
The cryptographic layer has zero external dependencies for encryption. All file, metadata, note, and chat encryption uses only the browser's built-in Web Crypto API. Argon2id (used for authentication and key derivation) uses hash-wasm, a WebAssembly implementation.
Криптографический слой имеет нулевые внешние зависимости для шифрования. Все шифрование файлов, метаданных, заметок и чата использует только встроенный в браузер Web Crypto API. Argon2id (используемый для аутентификации и деривации ключей) использует hash-wasm, реализацию на WebAssembly.
Die kryptografische Schicht hat null externe Abhängigkeiten für die Verschlüsselung. Alle Datei-, Metadaten-, Notiz- und Chat-Verschlüsselung verwendet nur die browserintegrierte Web Crypto API. Argon2id (für Authentifizierung und Schlüsselableitung) verwendet hash-wasm, eine WebAssembly-Implementierung.
La capa criptográfica tiene cero dependencias externas para el cifrado. Todo el cifrado de archivos, metadatos, notas y chat utiliza solo la Web Crypto API integrada del navegador. Argon2id (usado para autenticación y derivación de claves) usa hash-wasm, una implementación WebAssembly.
A camada criptográfica tem zero dependências externas para criptografia. Toda a criptografia de arquivos, metadados, notas e chat usa apenas a Web Crypto API integrada do navegador. Argon2id (usado para autenticação e derivação de chaves) usa hash-wasm, uma implementação WebAssembly.
Each purpose-specific sub-key is derived using HKDF with a unique info parameter, ensuring that compromising one sub-key does not compromise others.
Каждый целевой подключ выводится с помощью HKDF с уникальным параметром info, что гарантирует: компрометация одного подключа не компрометирует остальные.
Jeder zweckgebundene Unterschlüssel wird über HKDF mit einem einzigartigen info-Parameter abgeleitet, wodurch sichergestellt wird, dass die Kompromittierung eines Unterschlüssels keine anderen gefährdet.
Cada subclave de propósito específico se deriva usando HKDF con un parámetro info único, asegurando que comprometer una subclave no comprometa las demas.
Cada subchave de propósito específico e derivada usando HKDF com um parámetro info único, garantindo que comprometer uma subchave nao comprometa as demais.
| Parameter | Value | Параметр | Значение | Parameter | Wert | Parámetro | Valor | Parámetro | Valor |
|---|---|---|---|---|---|---|---|---|---|
| Algorithm | Argon2id (via hash-wasm WASM) | Алгоритм | Argon2id (через hash-wasm WASM) | Algorithmus | Argon2id (über hash-wasm WASM) | Algoritmo | Argon2id (via hash-wasm WASM) | Algoritmo | Argon2id (via hash-wasm WASM) |
| Memory | 65,536 KB (64 MB) | Память | 65 536 КБ (64 МБ) | Speicher | 65.536 KB (64 MB) | Memoria | 65.536 KB (64 MB) | Memoria | 65.536 KB (64 MB) |
| Iterations | 3 | Итерации | 3 | Iterationen | 3 | Iteraciones | 3 | Iteracoes | 3 |
| Parallelism | 4 lanes | Параллелизм | 4 потока | Parallelität | 4 Lanes | Paralelismo | 4 carriles | Paralelismo | 4 lanes |
| Hash length | 32 bytes (256 bits) | Длина хеша | 32 байта (256 бит) | Hash-Länge | 32 Bytes (256 Bit) | Longitud del hash | 32 bytes (256 bits) | Comprimento do hash | 32 bytes (256 bits) |
| Salt | 32 bytes, crypto.getRandomValues(), per-user, stored server-side | Соль | 32 байта, crypto.getRandomValues(), для каждого пользователя, хранится на сервере | Salt | 32 Bytes, crypto.getRandomValues(), pro Benutzer, serverseitig gespeichert | Salt | 32 bytes, crypto.getRandomValues(), por usuario, almacenado en el servidor | Salt | 32 bytes, crypto.getRandomValues(), por usuario, armazenado no servidor |
| Output | 256-bit AES-GCM CryptoKey (extractable) | Выход | 256-bit AES-GCM CryptoKey (извлекаемый) | Ausgabe | 256-Bit AES-GCM CryptoKey (extrahierbar) | Salida | 256-bit AES-GCM CryptoKey (extraible) | Saida | 256-bit AES-GCM CryptoKey (extraivel) |
| Parameter | Value | Параметр | Значение | Parameter | Wert | Parámetro | Valor | Parámetro | Valor |
|---|---|---|---|---|---|---|---|---|---|
| Algorithm | PBKDF2-HMAC-SHA256 (Web Crypto API native) | Алгоритм | PBKDF2-HMAC-SHA256 (нативный Web Crypto API) | Algorithmus | PBKDF2-HMAC-SHA256 (Web Crypto API nativ) | Algoritmo | PBKDF2-HMAC-SHA256 (Web Crypto API nativo) | Algoritmo | PBKDF2-HMAC-SHA256 (Web Crypto API nativo) |
| Iterations | 600,000 | Итерации | 600 000 | Iterationen | 600.000 | Iteraciones | 600.000 | Iteracoes | 600.000 |
| Salt | 32 bytes, per-user | Соль | 32 байта, для каждого пользователя | Salt | 32 Bytes, pro Benutzer | Salt | 32 bytes, por usuario | Salt | 32 bytes, por usuario |
| Output | 256-bit AES-GCM CryptoKey (extractable) | Выход | 256-bit AES-GCM CryptoKey (извлекаемый) | Ausgabe | 256-Bit AES-GCM CryptoKey (extrahierbar) | Salida | 256-bit AES-GCM CryptoKey (extraible) | Saida | 256-bit AES-GCM CryptoKey (extraivel) |
Argon2id is now used for both authentication and key derivation for v2 users (all new registrations and migrated accounts). Argon2id provides memory-hard protection against GPU/ASIC brute-force attacks, a significant improvement over PBKDF2. The hash-wasm library provides the Argon2id implementation via WebAssembly. PBKDF2 with 600,000 iterations remains as a legacy fallback for v1 users who have not yet logged in to trigger automatic migration. The kdf_version field in the database tracks which KDF each account uses.
Argon2id теперь используется как для аутентификации, так и для деривации ключей для пользователей v2 (все новые регистрации и мигрированные аккаунты). Argon2id обеспечивает защиту с высокими требованиями к памяти против брутфорс-атак на GPU/ASIC, что является значительным улучшением по сравнению с PBKDF2. Библиотека hash-wasm предоставляет реализацию Argon2id через WebAssembly. PBKDF2 с 600 000 итерациями остается как устаревший откат для пользователей v1, которые еще не выполнили вход для запуска автоматической миграции. Поле kdf_version в базе данных отслеживает, какой KDF использует каждый аккаунт.
Argon2id wird jetzt sowohl für die Authentifizierung als auch für die Schlüsselableitung verwendet für v2-Benutzer (alle neuen Registrierungen und migrierte Konten). Argon2id bietet speicherintensiven Schutz gegen GPU/ASIC-Brute-Force-Angriffe, eine erhebliche Verbesserung gegenüber PBKDF2. Die hash-wasm-Bibliothek stellt die Argon2id-Implementierung über WebAssembly bereit. PBKDF2 mit 600.000 Iterationen bleibt als Legacy-Fallback für v1-Benutzer erhalten, die sich noch nicht angemeldet haben, um die automatische Migration auszulösen. Das Feld kdf_version in der Datenbank verfolgt, welchen KDF jedes Konto verwendet.
Argon2id ahora se usa tanto para autenticación como para derivación de claves para usuarios v2 (todos los registros nuevos y cuentas migradas). Argon2id proporciona protección con altos requisitos de memoria contra ataques de fuerza bruta con GPU/ASIC, una mejora significativa sobre PBKDF2. La biblioteca hash-wasm proporciona la implementación de Argon2id via WebAssembly. PBKDF2 con 600.000 iteraciones permanece como respaldo legacy para usuarios v1 que aun no han iniciado sesion para activar la migracion automatica. El campo kdf_version en la base de datos rastrea que KDF usa cada cuenta.
Argon2id agora e usado tanto para autenticação quanto para derivação de chaves para usuarios v2 (todos os novos registros e contas migradas). Argon2id fornece proteção com altos requisitos de memoria contra ataques de forca bruta com GPU/ASIC, uma melhoria significativa sobre PBKDF2. A biblioteca hash-wasm fornece a implementação do Argon2id via WebAssembly. PBKDF2 com 600.000 iterações permanece como fallback legacy para usuarios v1 que ainda nao fizeram login para acionar a migracao automatica. O campo kdf_version no banco de dados rastreia qual KDF cada conta usa.
| Parameter | Value | Параметр | Значение | Parameter | Wert | Parámetro | Valor | Parámetro | Valor |
|---|---|---|---|---|---|---|---|---|---|
| Algorithm | HKDF-SHA256 | Алгоритм | HKDF-SHA256 | Algorithmus | HKDF-SHA256 | Algoritmo | HKDF-SHA256 | Algoritmo | HKDF-SHA256 |
| Salt | 'darkcloud-v1' (version constant) | Соль | 'darkcloud-v1' (константа версии) | Salt | 'darkcloud-v1' (Versionskonstante) | Salt | 'darkcloud-v1' (constante de version) | Salt | 'darkcloud-v1' (constante de versão) |
| Info | Purpose string (e.g., "file-encryption") | Info | Строка назначения (напр., "file-encryption") | Info | Zweckzeichenfolge (z.B. "file-encryption") | Info | Cadena de propósito (ej., "file-encryption") | Info | String de propósito (ex., "file-encryption") |
| Output | 256-bit AES-GCM CryptoKey (non-extractable) | Выход | 256-bit AES-GCM CryptoKey (неизвлекаемый) | Ausgabe | 256-Bit AES-GCM CryptoKey (nicht extrahierbar) | Salida | 256-bit AES-GCM CryptoKey (no extraible) | Saida | 256-bit AES-GCM CryptoKey (nao extraivel) |
Why fixed HKDF salt: Per RFC 5869, HKDF salt is optional. Domain separation is provided by the info parameter. Per-user randomization already occurs at the KDF layer (unique random salt per user for Argon2id/PBKDF2). The version constant enables future protocol upgrades.
Почему фиксированная соль HKDF: Согласно RFC 5869, соль HKDF необязательна. Разделение доменов обеспечивается параметром info. Рандомизация для каждого пользователя уже происходит на уровне KDF (уникальная случайная соль для Argon2id/PBKDF2). Константа версии позволяет обновлять протокол в будущем.
Warum fester HKDF-Salt: Gemäß RFC 5869 ist der HKDF-Salt optional. Die Domänentrennung wird durch den info-Parameter bereitgestellt. Die benutzerspezifische Randomisierung erfolgt bereits auf KDF-Ebene (einzigartiger zufälliger Salt pro Benutzer für Argon2id/PBKDF2). Die Versionskonstante ermöglicht zukünftige Protokoll-Upgrades.
Por que salt HKDF fijo: Segun RFC 5869, el salt HKDF es opcional. La separacion de dominios la proporciona el parámetro info. La aleatorizacion por usuario ya ocurre en la capa KDF (salt aleatorio único por usuario para Argon2id/PBKDF2). La constante de version permite futuras actualizaciones del protocolo.
Por que salt HKDF fixo: Conforme RFC 5869, o salt HKDF e opcional. A separacao de dominio e fornecida pelo parámetro info. A randomizacao por usuario ja ocorre na camada KDF (salt aleatorio único por usuario para Argon2id/PBKDF2). A constante de versão permite futuras atualizações do protocolo.
| Parameter | Value | Параметр | Значение | Parameter | Wert | Parámetro | Valor | Parámetro | Valor |
|---|---|---|---|---|---|---|---|---|---|
| Algorithm | Argon2id | Алгоритм | Argon2id | Algorithmus | Argon2id | Algoritmo | Argon2id | Algoritmo | Argon2id |
| Memory cost | 65,536 KB (64 MB) | Стоимость памяти | 65 536 КБ (64 МБ) | Speicherkosten | 65.536 KB (64 MB) | Costo de memoria | 65.536 KB (64 MB) | Custo de memoria | 65.536 KB (64 MB) |
| Time cost | 3 iterations | Стоимость времени | 3 итерации | Zeitkosten | 3 Iterationen | Costo de tiempo | 3 iteraciones | Custo de tempo | 3 iterações |
| Parallelism | 4 lanes | Параллелизм | 4 потока | Parallelität | 4 Lanes | Paralelismo | 4 carriles | Paralelismo | 4 lanes |
For v2 users, the Argon2id authentication hash is computed client-side using a separate auth_salt (distinct from the key derivation salt). The server never receives the raw password. It stores the Argon2id hash and performs constant-time comparison on login. The authentication hash and the key derivation use separate salts, ensuring the authentication credential cannot be used to derive encryption keys. For v1 legacy users, the server performs server-side Argon2id verification of the raw password. Migration from v1 to v2 happens automatically on login: the client sends both the legacy password and the new client-side hash, and the server updates the stored credential.
Для пользователей v2 хеш аутентификации Argon2id вычисляется на стороне клиента с использованием отдельной auth_salt (отличной от соли деривации ключей). Сервер никогда не получает исходный пароль. Он хранит хеш Argon2id и выполняет сравнение с постоянным временем при входе. Хеш аутентификации и деривация ключей используют разные соли, что гарантирует невозможность использования учетных данных аутентификации для деривации ключей шифрования. Для устаревших пользователей v1 сервер выполняет серверную верификацию Argon2id исходного пароля. Миграция с v1 на v2 происходит автоматически при входе: клиент отправляет как устаревший пароль, так и новый клиентский хеш, и сервер обновляет хранимые учетные данные.
Für v2-Benutzer wird der Argon2id-Authentifizierungshash clientseitig mit einem separaten auth_salt berechnet (unterschiedlich vom Schlüsselableitungs-Salt). Der Server erhält nie das Rohpasswort. Er speichert den Argon2id-Hash und führt beim Login einen zeitkonstanten Vergleich durch. Der Authentifizierungshash und die Schlüsselableitung verwenden separate Salts, sodass die Authentifizierungsdaten nicht zur Ableitung von Verschlüsselungsschlüsseln verwendet werden können. Für Legacy-v1-Benutzer führt der Server eine serverseitige Argon2id-Verifizierung des Rohpassworts durch. Die Migration von v1 zu v2 erfolgt automatisch beim Login: Der Client sendet sowohl das Legacy-Passwort als auch den neuen clientseitigen Hash, und der Server aktualisiert die gespeicherten Anmeldedaten.
Para usuarios v2, el hash de autenticación Argon2id se calcula del lado del cliente usando un auth_salt separado (distinto del salt de derivación de claves). El servidor nunca recibe la contraseña en bruto. Almacena el hash Argon2id y realiza una comparación de tiempo constante al iniciar sesión. El hash de autenticación y la derivación de claves usan salts separados, asegurando que la credencial de autenticación no pueda usarse para derivar claves de cifrado. Para usuarios legacy v1, el servidor realiza verificación Argon2id del lado del servidor de la contraseña en bruto. La migración de v1 a v2 ocurre automáticamente al iniciar sesión: el cliente envía tanto la contraseña legacy como el nuevo hash del lado del cliente, y el servidor actualiza la credencial almacenada.
Para usuarios v2, o hash de autenticação Argon2id e calculado no lado do cliente usando um auth_salt separado (distinto do salt de derivação de chaves). O servidor nunca recebe a senha bruta. Ele armazena o hash Argon2id e realiza comparação de tempo constante no login. O hash de autenticação e a derivação de chaves usam salts separados, garantindo que a credencial de autenticação nao possa ser usada para derivar chaves de criptografia. Para usuarios legacy v1, o servidor realiza verificação Argon2id do lado do servidor da senha bruta. A migracao de v1 para v2 ocorre automaticamente no login: o cliente envia tanto a senha legacy quanto o novo hash do lado do cliente, e o servidor atualiza a credencial armazenada.
| Parameter | Value | Параметр | Значение | Parameter | Wert | Parámetro | Valor | Parámetro | Valor |
|---|---|---|---|---|---|---|---|---|---|
| Algorithm | AES-256-GCM (Galois/Counter Mode) | Алгоритм | AES-256-GCM (Galois/Counter Mode) | Algorithmus | AES-256-GCM (Galois/Counter Mode) | Algoritmo | AES-256-GCM (Galois/Counter Mode) | Algoritmo | AES-256-GCM (Galois/Counter Mode) |
| Key size | 256 bits | Размер ключа | 256 бит | Schlüsselgröße | 256 Bit | Tamaño de clave | 256 bits | Tamanho da chave | 256 bits |
| IV (Nonce) | 96 bits (12 bytes), crypto.getRandomValues() | IV (Nonce) | 96 бит (12 байт), crypto.getRandomValues() | IV (Nonce) | 96 Bit (12 Bytes), crypto.getRandomValues() | IV (Nonce) | 96 bits (12 bytes), crypto.getRandomValues() | IV (Nonce) | 96 bits (12 bytes), crypto.getRandomValues() |
| Auth tag | 128 bits (built into GCM) | Тег аутентификации | 128 бит (встроен в GCM) | Auth-Tag | 128 Bit (in GCM integriert) | Tag de autenticación | 128 bits (integrado en GCM) | Tag de autenticação | 128 bits (integrado ao GCM) |
| AAD | File ID (UTF-8 encoded, v2 format) | AAD | ID файла (UTF-8, формат v2) | AAD | Datei-ID (UTF-8-kodiert, v2-Format) | AAD | ID de archivo (codificado UTF-8, formato v2) | AAD | ID do arquivo (codificado UTF-8, formato v2) |
AES-GCM provides both confidentiality (encryption) and authenticity (tamper detection). A unique random IV is generated for every encryption operation using the browser's CSPRNG.
AES-GCM обеспечивает как конфиденциальность (шифрование), так и аутентичность (обнаружение подделки). Уникальный случайный IV генерируется для каждой операции шифрования с использованием CSPRNG браузера.
AES-GCM bietet sowohl Vertraulichkeit (Verschlüsselung) als auch Authentizität (Manipulationserkennung). Für jede Verschlüsselungsoperation wird ein einzigartiger zufälliger IV mit dem CSPRNG des Browsers generiert.
AES-GCM proporciona tanto confidencialidad (cifrado) como autenticidad (detección de manipulación). Se genera un IV aleatorio único para cada operacion de cifrado utilizando el CSPRNG del navegador.
AES-GCM fornece tanto confidencialidade (criptografia) quanto autenticidade (detecção de adulteracao). Um IV aleatorio único e gerado para cada operacao de criptografia usando o CSPRNG do navegador.
v1 (legacy): [12-byte IV][ciphertext][16-byte auth tag]
v2 (current): [0x02][12-byte IV][ciphertext][16-byte auth tag]
AAD = fileId (UTF-8)
Version detection: First byte 0x02 indicates v2 format with AAD. Any other first byte triggers v1 fallback (no AAD). This ensures backward compatibility - files encrypted before AAD introduction remain readable.
Определение версии: Первый байт 0x02 указывает формат v2 с AAD. Любой другой первый байт запускает откат к v1 (без AAD). Это обеспечивает обратную совместимость - файлы, зашифрованные до введения AAD, остаются читаемыми.
Versionserkennung: Erstes Byte 0x02 zeigt v2-Format mit AAD an. Jedes andere erste Byte lost v1-Fallback aus (ohne AAD). Dies gewährleistet Abwärtskompatibilität - Dateien, die vor der AAD-Einführung verschlüsselt wurden, bleiben lesbar.
Deteccion de version: El primer byte 0x02 indica formato v2 con AAD. Cualquier otro primer byte activa el respaldo v1 (sin AAD). Esto garantiza compatibilidad retroactiva - los archivos cifrados antes de la introduccion de AAD siguen siendo legibles.
Detecção de versão: O primeiro byte 0x02 indica formato v2 com AAD. Qualquer outro primeiro byte aciona o fallback v1 (sem AAD). Isso garante compatibilidade retroativa - arquivos criptografados antes da introducao do AAD permanecem legiveis.
In v2 format, the file's unique UUID is passed as Additional Authenticated Data to AES-GCM. This cryptographically binds the ciphertext to a specific file ID. If a malicious server swaps one file's ciphertext for another, decryption fails because the AAD (fileId) won't match.
В формате v2 уникальный UUID файла передается как Additional Authenticated Data в AES-GCM. Это криптографически привязывает шифротекст к конкретному ID файла. Если злонамеренный сервер подменит шифротекст одного файла другим, расшифровка не удастся, так как AAD (fileId) не совпадет.
Im v2-Format wird die einzigartige UUID der Datei als Additional Authenticated Data an AES-GCM übergeben. Dies bindet den Chiffretext kryptografisch an eine bestimmte Datei-ID. Wenn ein bösartiger Server den Chiffretext einer Datei gegen einen anderen austauscht, schlagt die Entschlusselung fehl, da die AAD (fileId) nicht übereinstimmt.
En formato v2, el UUID único del archivo se pasa como Additional Authenticated Data a AES-GCM. Esto vincula criptográficamente el texto cifrado a un ID de archivo específico. Si un servidor malicioso intercambia el texto cifrado de un archivo por otro, el descifrado falla porque el AAD (fileId) no coincidira.
No formato v2, o UUID único do arquivo e passado como Additional Authenticated Data ao AES-GCM. Isso vincula criptográficamente o texto cifrado a um ID de arquivo específico. Se um servidor malicioso trocar o texto cifrado de um arquivo por outro, a descriptografia falha porque o AAD (fileId) nao correspondera.
Each file is encrypted with its own unique random 256-bit key (DEK), generated via crypto.subtle.generateKey(). The DEK encrypts the file content. The DEK itself is then wrapped (encrypted) with the user's file-encryption sub-key and stored alongside the file.
Каждый файл шифруется собственным уникальным случайным 256-битным ключом (DEK), сгенерированным через crypto.subtle.generateKey(). DEK шифрует содержимое файла. Сам DEK затем оборачивается (шифруется) подключом шифрования файлов пользователя и хранится вместе с файлом.
Jede Datei wird mit ihrem eigenen einzigartigen zufälligen 256-Bit-Schlüssel (DEK) verschlüsselt, generiert über crypto.subtle.generateKey(). Der DEK verschlüsselt den Dateiinhalt. Der DEK selbst wird dann mit dem Dateiverschlüsselungs-Unterschlüssel des Benutzers umschlossen (verschlüsselt) und zusammen mit der Datei gespeichert.
Cada archivo se cifra con su propia clave aleatoria única de 256 bits (DEK), generada via crypto.subtle.generateKey(). El DEK cifra el contenido del archivo. El DEK mismo se envuelve (cifra) con la subclave de cifrado de archivos del usuario y se almacena junto al archivo.
Cada arquivo e criptografado com sua propria chave aleatoria única de 256 bits (DEK), gerada via crypto.subtle.generateKey(). O DEK criptografa o conteudo do arquivo. O DEK e entao envolvido (criptografado) com a subchave de criptografia de arquivos do usuario e armazenado junto ao arquivo.
Upload: 1. DEK = generateKey(AES-256-GCM) // random per file 2. ciphertext = AES-GCM(DEK, plaintext, AAD=fileId) 3. wrappedDEK = AES-GCM(fileKey, DEK) // wrap with user's key 4. Store: ciphertext + wrappedDEK Download: 1. DEK = AES-GCM-decrypt(fileKey, wrappedDEK) // unwrap 2. plaintext = AES-GCM-decrypt(DEK, ciphertext, AAD=fileId)
Benefits of per-file DEK:
Преимущества DEK для каждого файла:
Vorteile des Pro-Datei-DEK:
Beneficios del DEK por archivo:
Beneficios do DEK por arquivo:
File names, types, and metadata are encrypted with a dedicated metadata-encryption sub-key using AES-256-GCM:
Имена файлов, типы и метаданные шифруются выделенным подключом metadata-encryption с использованием AES-256-GCM:
Dateinamen, Typen und Metadaten werden mit einem dedizierten metadata-encryption-Unterschlüssel unter Verwendung von AES-256-GCM verschlüsselt:
Los nombres de archivos, tipos y metadatos se cifran con una subclave dedicada de metadata-encryption usando AES-256-GCM:
Nomes de arquivos, tipos e metadados sao criptografados com uma subchave dedicada de metadata-encryption usando AES-256-GCM:
{
"ciphertext": "base64...", // Encrypted JSON: {type, lastModified, originalSize}
"iv": "base64..." // Unique 12-byte IV
}
A dedicated metadata-signing sub-key (HMAC-SHA256) signs the tuple (fileId, encryptedName, encryptedMeta). The signature is stored server-side and verified by the client on each file listing.
Выделенный подключ metadata-signing (HMAC-SHA256) подписывает кортеж (fileId, encryptedName, encryptedMeta). Подпись хранится на сервере и проверяется клиентом при каждом получении списка файлов.
Ein dedizierter metadata-signing-Unterschlüssel (HMAC-SHA256) signiert das Tupel (fileId, encryptedName, encryptedMeta). Die Signatur wird serverseitig gespeichert und vom Client bei jeder Dateiauflistung verifiziert.
Una subclave dedicada de metadata-signing (HMAC-SHA256) firma la tupla (fileId, encryptedName, encryptedMeta). La firma se almacena en el servidor y es verificada por el cliente en cada listado de archivos.
Uma subchave dedicada de metadata-signing (HMAC-SHA256) assina a tupla (fileId, encryptedName, encryptedMeta). A assinatura e armazenada no servidor e verificada pelo cliente em cada listagem de arquivos.
signature = HMAC-SHA256(signingKey, fileId + ":" + encryptedName + ":" + encryptedMeta)
Files without signatures (uploaded before this feature) are displayed normally but without integrity verification. New files always include signatures.
Файлы без подписей (загруженные до появления этой функции) отображаются нормально, но без проверки целостности. Новые файлы всегда включают подписи.
Dateien ohne Signaturen (vor dieser Funktion hochgeladen) werden normal angezeigt, aber ohne Integritätsverifizierung. Neue Dateien enthalten immer Signaturen.
Los archivos sin firmas (subidos antes de esta función) se muestran normalmente pero sin verificación de integridad. Los nuevos archivos siempre incluyen firmas.
Arquivos sem assinaturas (enviados antes desta funciónalidade) sao exibidos normalmente, mas sem verificação de integridade. Novos arquivos sempre incluem assinaturas.
sifero.cloud/s/shareId#shareKeysifero.cloud/s/shareId#shareKeysifero.cloud/s/shareId#shareKeysifero.cloud/s/shareId#shareKeysifero.cloud/s/shareId#shareKeyThe URL fragment (#) is never sent to the server per HTTP specification. The server sees only the share ID, never the decryption key.
Фрагмент URL (#) никогда не отправляется на сервер согласно спецификации HTTP. Сервер видит только ID ссылки, но не ключ расшифровки.
Das URL-Fragment (#) wird gemaess HTTP-Spezifikation nie an den Server gesendet. Der Server sieht nur die Freigabe-ID, nie den Entschlusselungsschlussel.
El fragmento de URL (#) nunca se envia al servidor segun la específicacion HTTP. El servidor ve solo el ID de comparticion, nunca la clave de descifrado.
O fragmento da URL (#) nunca e enviado ao servidor conforme a específicacao HTTP. O servidor ve apenas o ID de compartilhamento, nunca a chave de descriptografia.
| Attack vector | Protection | Вектор атаки | Защита | Angriffsvektor | Schutz | Vector de ataque | Protección | Vetor de ataque | Proteção |
|---|---|---|---|---|---|---|---|---|---|
| Server logs | Fragment not included in HTTP requests | Логи сервера | Фрагмент не включается в HTTP-запросы | Server-Logs | Fragment nicht in HTTP-Anfragen enthalten | Logs del servidor | Fragmento no incluido en solicitudes HTTP | Logs do servidor | Fragmento nao incluido em requisicoes HTTP |
| Referrer header | Referrer-Policy: strict-origin-when-cross-origin | Заголовок Referrer | Referrer-Policy: strict-origin-when-cross-origin | Referrer-Header | Referrer-Policy: strict-origin-when-cross-origin | Encabezado Referrer | Referrer-Policy: strict-origin-when-cross-origin | Cabeçalho Referrer | Referrer-Policy: strict-origin-when-cross-origin |
| Analytics/trackers | Zero third-party scripts on share pages | Аналитика/трекеры | Нулевое количество сторонних скриптов на страницах общего доступа | Analytics/Tracker | Keine Drittanbieter-Skripte auf Freigabeseiten | Analytics/rastreadores | Cero scripts de terceros en paginas de comparticion | Analytics/rastreadores | Zero scripts de terceiros em paginas de compartilhamento |
| Preview bots | Bots don't execute JS, can't access fragment | Боты превью | Боты не выполняют JS, не могут получить доступ к фрагменту | Vorschau-Bots | Bots führen kein JS aus, können nicht auf Fragment zugreifen | Bots de vista previa | Los bots no ejecutan JS, no pueden acceder al fragmento | Bots de preview | Bots nao executam JS, nao podem acessar o fragmento |
| Browser history | Full URL stored locally (user responsibility) | История браузера | Полный URL хранится локально (ответственность пользователя) | Browser-Verlauf | Vollstandige URL lokal gespeichert (Benutzerverantwortung) | Historial del navegador | URL completa almacenada localmente (responsabilidad del usuario) | Historico do navegador | URL completa armazenada localmente (responsabilidade do usuario) |
| Feature | Implementation | Функция | Реализация | Funktion | Implementierung | Función | Implementación | Funciónalidade | Implementação |
|---|---|---|---|---|---|---|---|---|---|
| Password protection | Argon2id hash stored server-side, verified before serving blob | Защита паролем | Хеш Argon2id хранится на сервере, проверяется перед отдачей блоба | Passwortschutz | Argon2id-Hash serverseitig gespeichert, vor Auslieferung des Blobs verifiziert | Protección con contraseña | Hash Argon2id almacenado en el servidor, verificado antes de servir el blob | Proteção por senha | Hash Argon2id armazenado no servidor, verificado antes de servir o blob |
| Expiration (TTL) | Server-side enforcement, cron cleanup | Срок действия (TTL) | Контроль на сервере, очистка по cron | Ablauf (TTL) | Serverseitige Durchsetzung, Cron-Bereinigung | Expiración (TTL) | Aplicacion en el servidor, limpieza por cron | Expiração (TTL) | Aplicacao no servidor, limpeza por cron |
| Burn-after-read | Atomic SELECT FOR UPDATE transaction, file deleted after first download | Burn-after-read | Атомарная транзакция SELECT FOR UPDATE, файл удаляется после первого скачивания | Burn-after-read | Atomare SELECT FOR UPDATE Transaktion, Datei nach erstem Download gelöscht | Burn-after-read | Transaccion atomica SELECT FOR UPDATE, archivo eliminado despues de la primera descarga | Burn-after-read | Transacao atomica SELECT FOR UPDATE, arquivo excluido apos primeiro download |
| Max downloads | Atomic counter with row-level locking | Макс. скачиваний | Атомарный счетчик с блокировкой на уровне строки | Max. Downloads | Atomarer Zahler mit Zeilenebenen-Sperrung | Max. descargas | Contador atomico con bloqueo a nivel de fila | Max. downloads | Contador atomico com bloqueio em nivel de linha |
Dead Drop allows any user to receive files anonymously from anyone — without requiring the sender to register, log in, or be tracked in any way. The recipient generates a unique drop link; anyone with that link can encrypt and upload files that only the recipient can decrypt.
Dead Drop позволяет любому пользователю анонимно получать файлы от кого угодно — без регистрации, авторизации или какого-либо отслеживания отправителя. Получатель генерирует уникальную ссылку; любой, у кого есть эта ссылка, может зашифровать и загрузить файлы, которые сможет расшифровать только получатель.
Dead Drop ermöglicht es jedem Benutzer, anonym Dateien von beliebigen Personen zu empfangen — ohne dass sich der Absender registrieren, anmelden oder in irgendeiner Weise verfolgen lassen muss. Der Empfänger generiert einen einzigartigen Drop-Link; jeder mit diesem Link kann Dateien verschlüsseln und hochladen, die nur der Empfänger entschlüsseln kann.
Dead Drop permite a cualquier usuario recibir archivos de forma anónima de cualquier persona — sin que el remitente necesite registrarse, iniciar sesión o ser rastreado de ninguna manera. El destinatario genera un enlace único; cualquiera con ese enlace puede cifrar y subir archivos que solo el destinatario puede descifrar.
Dead Drop permite que qualquer usuário receba arquivos anonimamente de qualquer pessoa — sem que o remetente precise se registrar, fazer login ou ser rastreado de qualquer forma. O destinatário gera um link único; qualquer pessoa com esse link pode criptografar e enviar arquivos que apenas o destinatário pode descriptografar.
When a user creates a Dead Drop, a fresh RSA-4096 key pair is generated client-side via Web Crypto API. The public key is embedded in the drop URL (after the # fragment). The private key is wrapped (encrypted) with the user's master key using AES-256-GCM before being stored on the server. The server never sees the raw private key.
При создании Dead Drop на стороне клиента через Web Crypto API генерируется новая пара ключей RSA-4096. Открытый ключ встраивается в URL ссылки (после фрагмента #). Закрытый ключ оборачивается (шифруется) мастер-ключом пользователя с помощью AES-256-GCM перед отправкой на сервер. Сервер никогда не видит незашифрованный закрытый ключ.
Wenn ein Benutzer einen Dead Drop erstellt, wird ein neues RSA-4096-Schlüsselpaar clientseitig über die Web Crypto API generiert. Der öffentliche Schlüssel wird in die Drop-URL eingebettet (nach dem #-Fragment). Der private Schlüssel wird mit dem Master-Key des Benutzers mittels AES-256-GCM verschlüsselt, bevor er auf dem Server gespeichert wird. Der Server sieht niemals den unverschlüsselten privaten Schlüssel.
Cuando un usuario crea un Dead Drop, se genera un nuevo par de claves RSA-4096 en el lado del cliente mediante la Web Crypto API. La clave pública se incluye en la URL del drop (después del fragmento #). La clave privada se envuelve (cifra) con la clave maestra del usuario usando AES-256-GCM antes de almacenarse en el servidor. El servidor nunca ve la clave privada sin cifrar.
Quando um usuário cria um Dead Drop, um novo par de chaves RSA-4096 é gerado no lado do cliente via Web Crypto API. A chave pública é incorporada na URL do drop (após o fragmento #). A chave privada é envolvida (criptografada) com a chave mestra do usuário usando AES-256-GCM antes de ser armazenada no servidor. O servidor nunca vê a chave privada descriptografada.
The sender's browser performs hybrid RSA-OAEP + AES-256-GCM encryption entirely client-side:
Браузер отправителя выполняет гибридное шифрование RSA-OAEP + AES-256-GCM полностью на стороне клиента:
Der Browser des Absenders führt eine hybride RSA-OAEP + AES-256-GCM-Verschlüsselung vollständig clientseitig durch:
El navegador del remitente realiza un cifrado híbrido RSA-OAEP + AES-256-GCM completamente en el lado del cliente:
O navegador do remetente realiza criptografia híbrida RSA-OAEP + AES-256-GCM inteiramente no lado do cliente:
[2-byte key length (big-endian)][RSA-encrypted AES key][12-byte IV][AES-GCM ciphertext + tag]
| Field | Size | Description | Поле | Размер | Описание | Feld | Größe | Beschreibung | Campo | Tamaño | Descripción | Campo | Tamanho | Descrição |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Key length | 2 bytes | Length of the RSA-encrypted AES key (big-endian uint16) | Длина ключа | 2 байта | Длина RSA-зашифрованного AES-ключа (big-endian uint16) | Schlüssellänge | 2 Bytes | Länge des RSA-verschlüsselten AES-Schlüssels (Big-Endian uint16) | Longitud de clave | 2 bytes | Longitud de la clave AES cifrada con RSA (big-endian uint16) | Comprimento da chave | 2 bytes | Comprimento da chave AES criptografada com RSA (big-endian uint16) |
| RSA-encrypted AES key | 512 bytes (RSA-4096) | AES-256 key encrypted with RSA-OAEP (SHA-256) | RSA-зашифрованный AES-ключ | 512 байт (RSA-4096) | Ключ AES-256, зашифрованный RSA-OAEP (SHA-256) | RSA-verschlüsselter AES-Schlüssel | 512 Bytes (RSA-4096) | AES-256-Schlüssel verschlüsselt mit RSA-OAEP (SHA-256) | Clave AES cifrada con RSA | 512 bytes (RSA-4096) | Clave AES-256 cifrada con RSA-OAEP (SHA-256) | Chave AES criptografada com RSA | 512 bytes (RSA-4096) | Chave AES-256 criptografada com RSA-OAEP (SHA-256) |
| IV | 12 bytes | Initialization vector for AES-GCM | IV | 12 байт | Вектор инициализации для AES-GCM | IV | 12 Bytes | Initialisierungsvektor für AES-GCM | IV | 12 bytes | Vector de inicialización para AES-GCM | IV | 12 bytes | Vetor de inicialização para AES-GCM |
| Ciphertext + tag | Variable | AES-256-GCM encrypted file data with 128-bit authentication tag | Шифротекст + тег | Переменная | Зашифрованные данные файла AES-256-GCM с 128-битным тегом аутентификации | Chiffretext + Tag | Variabel | AES-256-GCM-verschlüsselte Dateidaten mit 128-Bit-Authentifizierungstag | Texto cifrado + etiqueta | Variable | Datos del archivo cifrados con AES-256-GCM con etiqueta de autenticación de 128 bits | Texto cifrado + tag | Variável | Dados do arquivo criptografados com AES-256-GCM com tag de autenticação de 128 bits |
#), which is never sent to the server#), который никогда не отправляется на сервер#), das niemals an den Server gesendet wird#), que nunca se envía al servidor#), que nunca é enviado ao servidorChat messages are end-to-end encrypted using per-room keys derived from the user's master key:
Сообщения чата шифруются сквозным шифрованием с использованием ключей для каждой комнаты, выведенных из мастер-ключа пользователя:
Chat-Nachrichten werden mit Ende-zu-Ende-Verschlüsselung unter Verwendung von pro-Raum-Schlüsseln verschlüsselt, die vom Master-Key des Benutzers abgeleitet werden:
Los mensajes del chat estan cifrados de extremo a extremo usando claves por sala derivadas de la clave maestra del usuario:
As mensagens do chat sao criptografadas de ponta a ponta usando chaves por sala derivadas da chave mestra do usuario:
chatKey = HKDF(masterKey, "chat-" + roomId) encryptedMessage = AES-256-GCM(chatKey, plaintext)
Each message is encrypted as a JSON string {ciphertext, iv} before transmission. The message payload itself is a JSON object {t: text, s: senderName}, meaning the sender name is encrypted within the message payload. The server stores the literal string "encrypted" as the sender_name column. Files shared in chat are also encrypted with the room's chat key.
Каждое сообщение шифруется как JSON-строка {ciphertext, iv} перед передачей. Содержимое сообщения представляет собой JSON-объект {t: текст, s: имяОтправителя}, что означает, что имя отправителя зашифровано внутри содержимого сообщения. Сервер хранит строку "encrypted" в столбце sender_name. Файлы, передаваемые в чате, также шифруются ключом чат-комнаты.
Jede Nachricht wird als JSON-String {ciphertext, iv} vor der Übertragung verschlüsselt. Der Nachrichteninhalt selbst ist ein JSON-Objekt {t: Text, s: Absendername}, was bedeutet, dass der Absendername innerhalb des Nachrichteninhalts verschlüsselt ist. Der Server speichert den Literalstring "encrypted" als sender_name-Spalte. In Chats geteilte Dateien werden ebenfalls mit dem Chat-Schlüssel des Raums verschlüsselt.
Cada mensaje se cifra como una cadena JSON {ciphertext, iv} antes de la transmision. El contenido del mensaje es un objeto JSON {t: texto, s: nombreRemitente}, lo que significa que el nombre del remitente esta cifrado dentro del contenido del mensaje. El servidor almacena la cadena literal "encrypted" como la columna sender_name. Los archivos compartidos en el chat tambien se cifran con la clave de chat de la sala.
Cada mensagem e criptografada como uma string JSON {ciphertext, iv} antes da transmissao. O conteudo da mensagem e um objeto JSON {t: texto, s: nomeRemetente}, o que significa que o nome do remetente e criptografado dentro do conteudo da mensagem. O servidor armazena a string literal "encrypted" como a coluna sender_name. Arquivos compartilhados no chat tambem sao criptografados com a chave de chat da sala.
Messages sent before E2E implementation are stored as plaintext and displayed with a fallback mechanism (decryption failure = display as-is).
Сообщения, отправленные до реализации E2E, хранятся в виде открытого текста и отображаются с механизмом отката (ошибка расшифровки = отображение как есть).
Nachrichten, die vor der E2E-Implementierung gesendet wurden, werden als Klartext gespeichert und mit einem Fallback-Mechanismus angezeigt (Entschlusselungsfehler = Anzeige wie vorliegend).
Los mensajes enviados antes de la implementacion E2E se almacenan como texto plano y se muestran con un mecanismo de respaldo (fallo de descifrado = mostrar tal cual).
Mensagens enviadas antes da implementacao E2E sao armazenadas como texto plano e exibidas com um mecanismo de fallback (falha de descriptografia = exibir como esta).
Anonymous signup: username + password only. No email, phone, or personal data required.
Анонимная регистрация: только имя пользователя + пароль. Не требуется email, телефон или личные данные.
Anonyme Registrierung: nur Benutzername + Passwort. Keine E-Mail, Telefon oder persönliche Daten erforderlich.
Registro anónimo: solo nombre de usuario + contraseña. No se requiere correo electrónico, telefono ni datos personales.
Registro anónimo: apenas nome de usuario + senha. Nao e necessario e-mail, telefone ou dados pessoais.
TOTP (RFC 6238) with 30-second window. QR code generated locally in the browser (no external API calls). Backup codes provided (SHA-256 hashed before storage). Rate-limited: 5 attempts per 15 minutes for disable operations.
TOTP (RFC 6238) с 30-секундным окном. QR-код генерируется локально в браузере (без внешних API-вызовов). Предоставляются резервные коды (хешируются SHA-256 перед сохранением). Ограничение частоты: 5 попыток за 15 минут для операций отключения.
TOTP (RFC 6238) mit 30-Sekunden-Fenster. QR-Code wird lokal im Browser generiert (keine externen API-Aufrufe). Backup-Codes bereitgestellt (SHA-256-gehasht vor Speicherung). Ratenbegrenzt: 5 Versuche pro 15 Minuten für Deaktivierungsoperationen.
TOTP (RFC 6238) con ventana de 30 segundos. Código QR generado localmente en el navegador (sin llamadas API externas). Codigos de respaldo proporcionados (hasheados con SHA-256 antes del almacenamiento). Limitado: 5 intentos cada 15 minutos para operaciones de desactivación.
TOTP (RFC 6238) com janela de 30 segundos. Código QR gerado localmente no navegador (sem chamadas de API externas). Codigos de backup fornecidos (hasheados com SHA-256 antes do armazenamento). Limitado: 5 tentativas por 15 minutos para operacoes de desativacao.
| Token storage | Memory only (not localStorage/sessionStorage) | Хранение токена | Только в памяти (не localStorage/sessionStorage) | Token-Speicherung | Nur im Speicher (nicht localStorage/sessionStorage) | Almacenamiento de token | Solo en memoria (no localStorage/sessionStorage) | Armazenamento de token | Apenas em memoria (nao localStorage/sessionStorage) |
| Token expiry | 24 hours | Истечение токена | 24 часа | Token-Ablauf | 24 Stunden | Expiración de token | 24 horas | Expiração do token | 24 horas |
| Inactivity timeout | 10 minutes (auto-logout, keys cleared) | Тайм-аут неактивности | 10 минут (автоматический выход, ключи удаляются) | Inaktivitats-Timeout | 10 Minuten (Auto-Logout, Schlüssel gelöscht) | Tiempo de inactividad | 10 minutos (cierre de sesión automatico, claves eliminadas) | Tempo de inatividade | 10 minutos (logout automatico, chaves apagadas) |
| Revocation | Per-token and per-user via Redis blacklist | Отзыв | По токену и по пользователю через черный список Redis | Widerruf | Pro Token und pro Benutzer über Redis-Blacklist | Revocación | Por token y por usuario via lista negra de Redis | Revogação | Por token e por usuario via lista negra do Redis |
| Brute force | Progressive delays: 0s → 1s → 2s → 5s → block | Брутфорс | Прогрессивные задержки: 0с → 1с → 2с → 5с → блокировка | Brute-Force | Progressive Verzögerungen: 0s → 1s → 2s → 5s → Sperre | Fuerza bruta | Retrasos progresivos: 0s → 1s → 2s → 5s → bloqueo | Forca bruta | Atrasos progressivos: 0s → 1s → 2s → 5s → bloqueio |
| Threat | Protection | Угроза | Защита | Bedrohung | Schutz | Amenaza | Protección | Ameaça | Proteção |
|---|---|---|---|---|---|---|---|---|---|
| Server compromise (data breach) | Attacker gets only encrypted blobs. Cannot decrypt without user passwords. | Компрометация сервера (утечка данных) | Злоумышленник получает только зашифрованные блобы. Не может расшифровать без паролей пользователей. | Serverkompromittierung (Datenleck) | Angreifer erhält nur verschlüsselte Blobs. Kann ohne Benutzerpasswörter nicht entschlüsseln. | Compromiso del servidor (brecha de datos) | El atacante obtiene solo blobs cifrados. No puede descifrar sin contraseñas de usuario. | Comprometimento do servidor (vazamento de dados) | O atacante obtem apenas blobs criptografados. Nao pode descriptografar sem senhas dos usuarios. |
| Server operator reading files | Zero-knowledge: operator has no access to plaintext or keys. | Чтение файлов оператором сервера | Zero-knowledge: оператор не имеет доступа к открытому тексту или ключам. | Server-Betreiber liest Dateien | Zero-Knowledge: Betreiber hat keinen Zugang zu Klartext oder Schlüsseln. | Operador del servidor leyendo archivos | Zero-knowledge: el operador no tiene acceso a texto plano ni claves. | Operador do servidor lendo arquivos | Zero-knowledge: o operador nao tem acesso a texto plano ou chaves. |
| Man-in-the-middle | HSTS preload, TLS 1.3, certificate pinning via HSTS. | Человек посередине | HSTS preload, TLS 1.3, привязка сертификата через HSTS. | Man-in-the-Middle | HSTS Preload, TLS 1.3, Zertifikat-Pinning über HSTS. | Man-in-the-middle | HSTS preload, TLS 1.3, fijacion de certificado via HSTS. | Man-in-the-middle | HSTS preload, TLS 1.3, fixacao de certificado via HSTS. |
| Brute-force login | Argon2id (64MB memory), progressive delays, IP-based lockout. | Брутфорс-атака на вход | Argon2id (64 МБ памяти), прогрессивные задержки, блокировка по IP. | Brute-Force-Login | Argon2id (64MB Speicher), progressive Verzögerungen, IP-basierte Sperrung. | Inicio de sesión por fuerza bruta | Argon2id (64MB de memoria), retrasos progresivos, bloqueo basado en IP. | Login por forca bruta | Argon2id (64MB de memoria), atrasos progressivos, bloqueio baseado em IP. |
| File swap by server | AAD binding (v2), HMAC metadata signatures. | Подмена файла сервером | Привязка AAD (v2), подписи метаданных HMAC. | Datei-Swap durch Server | AAD-Bindung (v2), HMAC-Metadaten-Signaturen. | Intercambio de archivos por el servidor | Vinculacion AAD (v2), firmas HMAC de metadatos. | Troca de arquivos pelo servidor | Vinculacao AAD (v2), assinaturas HMAC de metadados. |
| Share link interception (server) | Key in URL fragment, never sent to server. | Перехват ссылки общего доступа (сервер) | Ключ во фрагменте URL, никогда не отправляется на сервер. | Freigabelink-Abfang (Server) | Schlüssel im URL-Fragment, nie an Server gesendet. | Intercepcion de enlace compartido (servidor) | Clave en fragmento URL, nunca enviada al servidor. | Interceptacao de link compartilhado (servidor) | Chave no fragmento da URL, nunca enviada ao servidor. |
| Password reuse attacks | Unique 32-byte random salt per user for Argon2id key derivation. | Атаки повторного использования пароля | Уникальная 32-байтовая случайная соль для каждого пользователя для деривации ключей Argon2id. | Passwort-Wiederverwendungsangriffe | Einzigartiger 32-Byte zufälliger Salt pro Benutzer für Argon2id-Schlüsselableitung. | Ataques de reutilizacion de contraseñas | Salt aleatorio único de 32 bytes por usuario para derivación de claves Argon2id. | Ataques de reutilizacao de senhas | Salt aleatorio único de 32 bytes por usuario para derivação de chaves Argon2id. |
| Database compromise (panic tokens) | Panic Wipe tokens stored as SHA-256 hashes, not plaintext. | Компрометация базы данных (токены паники) | Токены Panic Wipe хранятся как хеши SHA-256, а не открытым текстом. | Datenbankkompromittierung (Panik-Token) | Panic-Wipe-Token als SHA-256-Hashes gespeichert, nicht als Klartext. | Compromiso de base de datos (tokens de panico) | Tokens de Panic Wipe almacenados como hashes SHA-256, no texto plano. | Comprometimento do banco de dados (tokens de panico) | Tokens de Panic Wipe armazenados como hashes SHA-256, nao texto plano. |
| Supply-chain attack (CDN/third-party) | Zero external JavaScript dependencies. Fonts and PDF viewer self-hosted. | Атака на цепочку поставок (CDN/сторонние) | Нулевые внешние JavaScript-зависимости. Шрифты и PDF-просмотрщик самостоятельно размещены. | Supply-Chain-Angriff (CDN/Drittanbieter) | Null externe JavaScript-Abhängigkeiten. Schriften und PDF-Viewer selbst gehostet. | Ataque a la cadena de suministro (CDN/terceros) | Cero dependências JavaScript externas. Fuentes y visor PDF autoalojados. | Ataque a cadeia de suprimentos (CDN/terceiros) | Zero dependências JavaScript externas. Fontes e visualizador PDF auto-hospedados. |
| Single-key compromise | Per-file DEK: each file encrypted with unique random key. One compromised key affects only one file. | Компрометация одного ключа | DEK для каждого файла: каждый файл зашифрован уникальным случайным ключом. Компрометация одного ключа затрагивает только один файл. | Einzelschlussel-Kompromittierung | Pro-Datei-DEK: jede Datei mit einzigartigem zufälliger Schlüssel verschlüsselt. Ein kompromittierter Schlüssel betrifft nur eine Datei. | Compromiso de una sola clave | DEK por archivo: cada archivo cifrado con clave aleatoria única. Una clave comprometida afecta solo un archivo. | Comprometimento de chave única | DEK por arquivo: cada arquivo criptografado com chave aleatoria única. Uma chave comprometida afeta apenas um arquivo. |
location.hash (share keys), intercept keyboard input (passwords), or export CryptoKey objects from memory.location.hash (ключи общего доступа), перехватывать ввод клавиатуры (пароли) или экспортировать объекты CryptoKey из памяти.location.hash (Freigabeschlussel) lesen, Tastatureingaben (Passwörter) abfangen oder CryptoKey-Objekte aus dem Speicher exportieren.location.hash (claves de comparticion), interceptar entrada de teclado (contraseñas) o exportar objetos CryptoKey de la memoria.location.hash (chaves de compartilhamento), interceptar entrada do teclado (senhas) ou exportar objetos CryptoKey da memoria.| Hosting | Hetzner Cloud, Helsinki, Finland (EU) | Хостинг | Hetzner Cloud, Хельсинки, Финляндия (ЕС) | Hosting | Hetzner Cloud, Helsinki, Finnland (EU) | Alojamiento | Hetzner Cloud, Helsinki, Finlandia (UE) | Hospedagem | Hetzner Cloud, Helsinquia, Finlandia (UE) |
| Jurisdiction | Georgia (outside Five Eyes / Fourteen Eyes) | Юрисдикция | Грузия (за пределами Five Eyes / Fourteen Eyes) | Rechtsgebiet | Georgien (außerhalb Five Eyes / Fourteen Eyes) | Jurisdicción | Georgia (fuera de Five Eyes / Fourteen Eyes) | Jurisdição | Georgia (fora dos Five Eyes / Fourteen Eyes) |
| TLS | Auto-managed via Caddy + Let's Encrypt, HSTS preload | TLS | Автоуправление через Caddy + Let's Encrypt, HSTS preload | TLS | Automatisch verwaltet über Caddy + Let's Encrypt, HSTS Preload | TLS | Gestionado automaticamente via Caddy + Let's Encrypt, HSTS preload | TLS | Gerenciado automaticamente via Caddy + Let's Encrypt, HSTS preload |
| Database | PostgreSQL 16 (encrypted blobs only, no PII columns) | База данных | PostgreSQL 16 (только зашифрованные блобы, без PII-столбцов) | Datenbank | PostgreSQL 16 (nur verschlüsselte Blobs, keine PII-Spalten) | Base de datos | PostgreSQL 16 (solo blobs cifrados, sin columnas PII) | Banco de dados | PostgreSQL 16 (apenas blobs criptografados, sem colunas PII) |
| Object storage | MinIO (S3-compatible, self-hosted) | Объектное хранилище | MinIO (S3-совместимое, самостоятельно размещенное) | Objektspeicher | MinIO (S3-kompatibel, selbst gehostet) | Almacenamiento de objetos | MinIO (compatible con S3, autoalojado) | Armazenamento de objetos | MinIO (compativel com S3, auto-hospedado) |
| Sessions | Redis (password-protected, localhost only) | Сессии | Redis (защищен паролем, только localhost) | Sitzungen | Redis (passwortgeschützt, nur localhost) | Sesiones | Redis (protegido por contraseña, solo localhost) | Sessões | Redis (protegido por senha, apenas localhost) |
| Backups | GPG-encrypted (AES-256), daily, 30-day retention, remote storage | Бэкапы | GPG-шифрование (AES-256), ежедневно, хранение 30 дней, удаленное хранилище | Backups | GPG-verschlüsselt (AES-256), täglich, 30-Tage-Aufbewahrung, Remote-Speicher | Copias de seguridad | Cifrado GPG (AES-256), diario, retencion de 30 dias, almacenamiento remoto | Backups | Criptografado com GPG (AES-256), diario, retencao de 30 dias, armazenamento remoto |
| Analytics | Self-hosted only. No Google Analytics, no third-party trackers. | Аналитика | Только самостоятельная. Без Google Analytics, без сторонних трекеров. | Analytics | Nur selbst gehostet. Kein Google Analytics, keine Drittanbieter-Tracker. | Analítica | Solo autoalojada. Sin Google Analytics, sin rastreadores de terceros. | Analítica | Apenas auto-hospedada. Sem Google Analytics, sem rastreadores de terceiros. |
| Payment processing | Dodo Payments (sees email at checkout only, no access to account data) | Обработка платежей | Dodo Payments (видит email только при оплате, без доступа к данным аккаунта) | Zahlungsabwicklung | Dodo Payments (sieht E-Mail nur beim Checkout, kein Zugang zu Kontodaten) | Procesamiento de pagos | Dodo Payments (ve el email solo en el pago, sin acceso a datos de cuenta) | Processamento de pagamentos | Dodo Payments (ve o email apenas no checkout, sem acesso a dados da conta) |
| External JS dependencies | None. All scripts loaded from self origin. Fonts (Inter) and PDF viewer (pdf.js) self-hosted. | Внешние JS-зависимости | Нет. Все скрипты загружаются со своего домена. Шрифты (Inter) и PDF-просмотрщик (pdf.js) самостоятельно размещены. | Externe JS-Abhängigkeiten | Keine. Alle Skripte vom eigenen Ursprung geladen. Schriften (Inter) und PDF-Viewer (pdf.js) selbst gehostet. | Dependencias JS externas | Ninguna. Todos los scripts cargados desde el mismo origen. Fuentes (Inter) y visor PDF (pdf.js) autoalojados. | Dependencias JS externas | Nenhuma. Todos os scripts carregados do proprio dominio. Fontes (Inter) e visualizador PDF (pdf.js) auto-hospedados. |
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; ... X-Frame-Options: DENY X-Content-Type-Options: nosniff Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: camera=(), microphone=(self), geolocation=(), payment=()
| Limitation | Status | Ограничение | Статус | Einschränkung | Status | Limitación | Estado | Limitação | Status |
|---|---|---|---|---|---|---|---|---|---|
| Support tickets stored in plaintext | Trade-off: admin must read and respond to tickets. Encryption would prevent support capability. | Тикеты поддержки хранятся в открытом виде | Компромисс: администратор должен читать и отвечать на тикеты. Шифрование сделало бы поддержку невозможной. | Support-Tickets als Klartext gespeichert | Kompromiss: Admin muss Tickets lesen und beantworten können. Verschlüsselung würde Support unmöglich machen. | Tickets de soporte almacenados en texto plano | Compromiso: el administrador debe leer y responder tickets. El cifrado impediria la capacidad de soporte. | Tickets de suporte armazenados em texto plano | Compromisso: o administrador deve ler e responder tickets. A criptografia impediria a capacidade de suporte. |
| Duress/deadman notification contacts in plaintext | Required: server must know email/Telegram to send alerts when duress login or deadman switch triggers. | Контакты уведомлений duress/deadman в открытом виде | Необходимо: сервер должен знать email/Telegram для отправки оповещений при входе под принуждением или срабатывании deadman switch. | Duress/Deadman-Benachrichtigungskontakte im Klartext | Erforderlich: Server muss E-Mail/Telegram kennen, um Benachrichtigungen bei Duress-Login oder Deadman-Switch auszulösen. | Contactos de notificación duress/deadman en texto plano | Requerido: el servidor debe conocer email/Telegram para enviar alertas cuando se activa el login de emergencia o deadman switch. | Contatos de notificação duress/deadman em texto plano | Necessario: o servidor deve conhecer email/Telegram para enviar alertas quando login de emergencia ou deadman switch e acionado. |
| No reproducible builds | Planned. Currently verifiable via DevTools source comparison with GitHub. | Нет воспроизводимых сборок | Планируется. В настоящее время можно проверить через DevTools, сравнивая исходники с GitHub. | Keine reproduzierbaren Builds | Geplant. Derzeit über DevTools-Quellvergleich mit GitHub verifizierbar. | Sin compilaciones reproducibles | Planificado. Actualmente verificable via comparacion de fuente DevTools con GitHub. | Sem builds reprodutiveis | Planejado. Atualmente verificavel via comparacao de fonte DevTools com GitHub. |
| No independent audit | Planned. Internal audits completed. External audit in evaluation. | Нет независимого аудита | Планируется. Внутренние аудиты завершены. Внешний аудит на рассмотрении. | Kein unabhängiges Audit | Geplant. Interne Audits abgeschlossen. Externes Audit in Bewertung. | Sin auditoria independiente | Planificado. Auditorias internas completadas. Auditoria externa en evaluacion. | Sem auditoria independente | Planejado. Auditorias internas concluidas. Auditoria externa em avaliacao. |
| Password change not available in UI | Planned. Requires client-side re-wrapping of all per-file DEKs with new master key. | Смена пароля недоступна в интерфейсе | Планируется. Требует повторной обертки всех DEK файлов новым мастер-ключом на клиенте. | Passwortänderung nicht in UI verfügbar | Geplant. Erfordert clientseitige Neu-Umschlusselung aller Pro-Datei-DEKs mit neuem Master-Key. | Cambio de contraseña no disponible en la interfaz | Planificado. Requiere re-envolver todos los DEKs por archivo con nueva clave maestra del lado del cliente. | Mudanca de senha nao disponivel na interface | Planejado. Requer re-envolvimento de todos os DEKs por arquivo com nova chave mestra do lado do cliente. |
| No file padding | File sizes visible to server. Acknowledged trade-off vs. storage efficiency. | Нет дополнения файлов | Размеры файлов видны серверу. Осознанный компромисс с эффективностью хранения. | Kein Datei-Padding | Dateigrößen für Server sichtbar. Anerkannter Kompromiss gegenüber Speichereffizienz. | Sin relleno de archivos | Tamaños de archivos visibles para el servidor. Compromiso reconocido vs. eficiencia de almacenamiento. | Sem preenchimento de arquivos | Tamanhos de arquivos visiveis ao servidor. Compromisso reconhecido vs. eficiencia de armazenamento. |
| CSS unsafe-inline in style-src | React uses inline styles. Removing requires significant refactoring. Script unsafe-inline already removed. | CSS unsafe-inline в style-src | React использует inline-стили. Удаление требует значительного рефакторинга. Script unsafe-inline уже удален. | CSS unsafe-inline in style-src | React verwendet Inline-Styles. Entfernung erfordert erhebliches Refactoring. Script unsafe-inline bereits entfernt. | CSS unsafe-inline en style-src | React usa estilos inline. Eliminarlo requiere refactorizacion significativa. Script unsafe-inline ya eliminado. | CSS unsafe-inline em style-src | React usa estilos inline. Remocao requer refatoracao significativa. Script unsafe-inline ja removido. |
| Anonymous chat (AnonChat) not E2E encrypted | By design: anonymous users without accounts have no shared key material. Authenticated chat rooms are fully E2E encrypted. | Анонимный чат (AnonChat) без E2E-шифрования | Намеренно: анонимные пользователи без аккаунтов не имеют общего ключевого материала. Авторизованные чат-комнаты полностью E2E-шифрованы. | Anonymer Chat (AnonChat) nicht E2E-verschlüsselt | Bewusst: anonyme Benutzer ohne Konten haben kein gemeinsames Schlüsselmaterial. Authentifizierte Chatraume sind vollständig E2E-verschlüsselt. | Chat anónimo (AnonChat) sin cifrado E2E | Por diseno: los usuarios anónimos sin cuentas no tienen material de clave compartido. Las salas de chat autenticadas estan completamente cifradas E2E. | Chat anónimo (AnonChat) sem criptografia E2E | Por design: usuarios anónimos sem contas nao tem material de chave compartilhado. Salas de chat autenticadas sao totalmente criptografadas E2E. |
Completed:
Завершено:
Abgeschlossen:
Completado:
Concluido:
Planned:
Запланировано:
Geplant:
Planificado:
Planejado:
| Priority | Item | Приоритет | Элемент | Priorität | Element | Prioridad | Elemento | Prioridade | Item |
|---|---|---|---|---|---|---|---|---|---|
| 1 | CI/CD with automated crypto tests and security regression checks | 1 | CI/CD с автоматизированными криптотестами и проверками регрессии безопасности | 1 | CI/CD mit automatisierten Kryptotests und Sicherheits-Regressionsprüfungen | 1 | CI/CD con pruebas criptográficas automatizadas y verificaciónes de regresion de seguridad | 1 | CI/CD com testes criptográficos automatizados e verificacoes de regressao de segurança |
| 2 | Published test vectors for external verification | 2 | Опубликованные тестовые векторы для внешней верификации | 2 | Veröffentlichte Testvektoren für externe Verifizierung | 2 | Vectores de prueba publicados para verificación externa | 2 | Vetores de teste publicados para verificação externa |
| 3 | Independent security audit (crypto layer + full service) | 3 | Независимый аудит безопасности (криптослой + полный сервис) | 3 | Unabhangiges Sicherheits-Audit (Kryptoschicht + vollständiger Service) | 3 | Auditoria de seguridad independiente (capa cripto + servicio completo) | 3 | Auditoria de segurança independente (camada cripto + servico completo) |
| 4 | Reproducible builds for web client | 4 | Воспроизводимые сборки для веб-клиента | 4 | Reproduzierbare Builds für Web-Client | 4 | Compilaciones reproducibles para cliente web | 4 | Builds reprodutiveis para cliente web |
| 5 | Desktop client / browser extension (code integrity verification) | 5 | Десктопный клиент / расширение браузера (верификация целостности кода) | 5 | Desktop-Client / Browser-Erweiterung (Code-Integritätsverifizierung) | 5 | Cliente de escritorio / extension de navegador (verificación de integridad de codigo) | 5 | Cliente desktop / extensao de navegador (verificação de integridade de codigo) |
| 6 | Formal bug bounty program | 6 | Формальная программа вознаграждения за уязвимости | 6 | Formales Bug-Bounty-Programm | 6 | Programa formal de recompensas por errores | 6 | Programa formal de recompensa por bugs |
This document describes the security architecture of Sifero Cloud as of April 2026.
For updates, see the open-source crypto module and changelog.
Report vulnerabilities to security@sifero.cloud.
Этот документ описывает архитектуру безопасности Sifero Cloud по состоянию на апрель 2026 года.
Для обновлений см. криптомодуль с открытым исходным кодом и журнал изменений.
Сообщайте об уязвимостях на security@sifero.cloud.
Dieses Dokument beschreibt die Sicherheitsarchitektur von Sifero Cloud, Stand April 2026.
Für Updates siehe das Open-Source-Kryptomodul und das Changelog.
Melden Sie Schwachstellen an security@sifero.cloud.
Este documento describe la arquitectura de seguridad de Sifero Cloud a abril de 2026.
Para actualizaciones, vea el módulo cripto de código abierto y el registro de cambios.
Reporte vulnerabilidades a security@sifero.cloud.
Este documento descreve a arquitetura de segurança do Sifero Cloud em abril de 2026.
Para atualizações, veja o módulo cripto de código aberto e o registro de alterações.
Reporte vulnerabilidades para security@sifero.cloud.