Бесплатный инструмент приватности
Запечатать файл
Зашифруйте файл новым одноразовым ключом и отправьте его любым каналом, каким захотите. Тот, у кого есть ключ, откроет его прямо здесь, на этой странице. Ничего никуда не загружается, парольной фразы, которую можно подобрать, здесь нет, а что внутри — видно до того, как что-либо сохранится.
Работает целиком в этой вкладке. Эта страница вообще не может обращаться к каким-либо серверам.
Запечатываем…
Запечатано.
Это ваш зашифрованный файл. Без ключа его не прочтёт никто. Ни мы, ни кто-либо ещё.
Ключ — показывается только сейчас
Этот ключ существует только на этой странице и только сейчас. Он нигде не сохраняется и никуда не отправляется. Если вы его потеряете, открыть файл не сможет никто, включая нас. Сохраните его, прежде чем уйти со страницы.
Или передайте ключ ссылкой
Ключ находится в ссылке после #. Эту часть браузеры никогда не отправляют ни на какой сервер. Ссылка открывает эту же страницу с уже готовой вкладкой «Открыть» и подставленным ключом, а затем убирает ключ из адресной строки.
Отправляйте файл и ключ по отдельности.
Открыть файл может любой, у кого есть и запечатанный файл, и ключ. Отправляйте их разными каналами: например, файл по почте, а ссылку с ключом сообщением. Тогда ни в одном ящике не окажется сразу и того и другого.
Ключ прочитан из вашей ссылки и удалён из адресной строки, чтобы не попасть в вашу историю.
Проверяем…
Что внутри этого запечатанного файла
Пока ничего не сохранено. Вот что, по словам самого запечатанного файла, в нём лежит:
- Имя
- Размер
- Тип
Осторожно: файлы этого типа могут выполнить код на вашем устройстве
Расшифровано.
Файл расшифрован на вашем устройстве и предложен к скачиванию. Ничто о нём не покидало эту страницу.
От создателей Sealby — зашифрованного сейфа для iPhone
Sealby хранит фото, файлы и заметки в зашифрованных сейфах на вашем iPhone. Без аккаунта, без серверов, и не прочтёт их никто, кроме вас.
Каждый параметр — названный
- Шифр
- AES-256-GCM (WebCrypto), 128-битный тег на каждый фрагмент
- Ключ
- 256 бит из CSPRNG браузера, новый для каждого запечатывания, используется один раз, ни из чего не выводится
- Разбиение на фрагменты
- сначала зашифрованный манифест (имя файла, размер, тип), затем сам файл фрагментами по 1 МиБ — каждый аутентифицируется отдельно
- Nonce
- 32-битная случайная соль запечатывания ‖ 64-битный счётчик фрагментов — внутри файла не повторяется никогда, да и ключ в любом случае одноразовый
- Аутентифицируемые данные
- весь 16-байтный заголовок плюс индекс каждого фрагмента и общее число фрагментов — перестановка, усечение или вклейка фрагментов ломают расшифровку
- Строка ключа
- base64url, 47 символов: 32-байтный ключ плюс 3-байтная контрольная сумма SHA-256, так что опечатка честно отклоняется, а не превращается в мусор
Честные ответы о том, что здесь происходит
Всё происходит в вашем браузере.
И запечатывание, и открытие читают файл в память этой страницы, прогоняют его там через AES-256-GCM встроенным в браузер движком WebCrypto и отдают результат обратно как загрузку. Ничего не отправляется на сервер. Нет ни аккаунта, ни обработки на стороне сервера. В отличие от остального сайта, эта страница не подгружает даже счётчик посещений без cookie. Никакой аналитики вообще.
Это не просто обещание. Страница отдаётся с Content-Security-Policy, которая разрешает браузеру загружать только собственные статические файлы этого сайта. У неё нет никакой возможности отправить ваш файл, ваш ключ или что-либо ещё на какой бы то ни было сервер, включая наш. Откройте инструменты разработчика в браузере во время запечатывания — и вы увидите ноль запросов. Для самого прямого доказательства установите набор инструментов и запечатайте файл в авиарежиме. При выключенной сети ничего не может уйти.
Ключ — это всё, и у нас его никогда нет.
При каждом запечатывании в вашем браузере создаётся новый случайный 256-битный ключ. Он показывается вам один раз и не хранится нигде: ни в наших системах (их здесь просто нет), ни в хранилище браузера, ни в самом запечатанном файле. Угадывать нечего — парольной фразы нет, и перебирать тоже нечего. Кто держит и ключ, и файл, тот откроет. У кого их нет — не откроет.
У этого есть жёсткое следствие: потерян ключ — потерян файл. Ни сброса, ни обращения в поддержку, ни восстановления. Мы не вредничаем. Копия, которую могли бы восстановить мы, была бы копией, которую кто-то может украсть или потребовать.
Ссылка с ключом никогда не доходит до сервера.
Ссылка для передачи помещает ключ в URL после #. Эта часть — фрагмент ссылки — остаётся в браузере. Она никогда не включается в то, что браузер отправляет на сервер, ни на наш, ни на чей-либо ещё. Когда эта страница открывается по ссылке с ключом, она читает ключ, переключается на вкладку «Открыть» и сразу же убирает ключ из адресной строки. Так он не остаётся в видимом URL и в истории браузера.
И всё же открыть файл может любой, у кого есть и ссылка, и запечатанный файл. Именно поэтому эта страница просит отправлять файл и ключ разными каналами.
Вы видите, что внутри, до того как что-либо сохранится.
Открытие происходит в два шага. Сначала страница расшифровывает только небольшой манифест: исходное имя файла, размер и тип. Она показывает его вам, с громким предупреждением для типов файлов, способных выполнять код (программы, скрипты, установщики, документы с макросами, HTML), и для имён, замаскированных двойным расширением вроде invoice.pdf.exe. Ничего не записывается, пока вы не нажмёте «расшифровать». Страница никогда не открывает и не отображает расшифрованное содержимое сама. Она лишь предлагает файл к скачиванию.
Стоит ясно понимать, что шифрование доказывает, а что нет. Запечатанный файл конфиденциален при передаче. Но само запечатывание ничего не говорит ни о том, кто его отправил, ни о том, безопасно ли его содержимое. Относитесь к неожиданному запечатанному файлу с тем же скепсисом, что и к неожиданному вложению.
Где на самом деле проходит граница доверия.
Вы выполняете код, который вам отдал этот сайт. Если бы sealby.app или ваше соединение с ним оказались скомпрометированы, вредоносная страница могла бы прочитать то, что вы в неё вводите. Это верно для любого веб-инструмента шифрования, и мы предпочитаем сказать это прямо, а не делать вид, что всё иначе. Что мы с этим делаем: страница — статический файл, и мы держим её свободной от стороннего кода. Установленный набор инструментов позволяет и дальше пользоваться уже загруженной версией. А формат описан ниже, чтобы под него можно было написать независимые инструменты.
Ваше собственное устройство тоже внутри этой границы. Расширения браузера с доступом к странице или вредоносное ПО на машине могут прочитать всё, что доступно любой странице. Сам запечатанный файл скрывает содержимое, но не всё. Любой, у кого он есть, видит его размер (примерно равный исходному) и то, что это файл, запечатанный Sealby.
Ограничения простыми словами
- Потерян ключ — потерян файл. Без исключений, так задумано.
- Мы не видим ваши файлы и ключи, а значит, не можем и проверить их на вредоносный код. Предупреждение о типе файла основано только на имени файла. Это не гарантия безопасности.
- Открыть файл может любой, у кого есть и запечатанный файл, и ключ. Инструмент не знает и не проверяет, кто это.
- Размер запечатанного файла примерно выдаёт размер исходного.
- Один файл до 100 МБ за одно запечатывание. Несколько файлов сначала упакуйте в архив.
Формат, байт за байтом
Всё, что нужно техническому читателю, чтобы независимо проверить вывод этой страницы или открыть файл .sealed тридцатью строками на Python:
| bytes | field | contents |
|---|---|---|
| 0–7 | magic | ASCII "SEALBY-W" |
| 8 | версия | 0x01 — всё остальное отклоняется как «создано более новой версией» |
| 9 | алгоритм | 0x01 = AES-256-GCM |
| 10–13 | соль запечатывания | 4 байта, CSPRNG, новая для каждого запечатывания |
| 14–15 | зарезервировано | должно быть нулями |
| 16–конец | кадры фрагментов | каждый: uint32 BE — длина шифротекста, затем шифротекст AES-GCM + 16-байтный тег |
Фрагмент 0 — это манифест: JSON в UTF-8 {"name":…,"size":…,"type":…}. Фрагменты 1…N−1 — сам файл кусками по 1 МиБ. Для фрагмента i из N: nonce = соль ‖ uint64 BE i; аутентифицируемые данные = заголовок ‖ uint64 BE i ‖ uint64 BE N. Поэтому подмена, усечение, перестановка, перенос и вклейка фрагментов из другого файла не проходят аутентификацию. Каждый случай подтверждён отдельным негативным тестом в репозитории.
Строка ключа: base64url (без набивки) от 32-байтного ключа, за которым идут первые 3 байта его SHA-256, всего 47 символов. При опечатке не сходится контрольная сумма, а не появляется мусор.
Полная побайтовая спецификация (FORMAT-WEB-v1) ·Тестовые векторы с известными ответами (JSON)
Эталонный открывающий скрипт (Python, библиотека cryptography)
import base64, hashlib, json, struct, sys
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
raw = open(sys.argv[1], "rb").read()
assert raw[:8] == b"SEALBY-W" and raw[8] == 1 and raw[9] == 1
assert raw[14:16] == b"\x00\x00"
header, salt = raw[:16], raw[10:14]
frames, off = [], 16
while off < len(raw):
(n,) = struct.unpack(">I", raw[off:off + 4]); off += 4
frames.append(raw[off:off + n]); off += n
assert off == len(raw)
kb = base64.urlsafe_b64decode(sys.argv[2] + "=") # 47-char key string
key, check = kb[:32], kb[32:35]
assert hashlib.sha256(key).digest()[:3] == check # typo check
N = len(frames)
def chunk(i):
nonce = salt + struct.pack(">Q", i)
aad = header + struct.pack(">QQ", i, N)
return AESGCM(key).decrypt(nonce, frames[i], aad)
manifest = json.loads(chunk(0))
data = b"".join(chunk(i) for i in range(1, N))
assert len(data) == manifest["size"]
open(manifest["name"], "wb").write(data)
print("decrypted ->", manifest["name"])Это для файлов в пути. Сейф — для файлов на хранении.
Запечатывание защищает файл, пока он куда-то едет. Sealby защищает всё, что остаётся: фото, файлы и заметки в зашифрованных сейфах на вашем iPhone. Без аккаунта, без серверов, и не прочтёт их никто, кроме вас.
iPhone и iPad · iOS 17+ · Бесплатно