Сразу дисклеймер: я ничего не продаю. share·me, бесплатный open-source проект под AGPL, без тарифов, подписок и регистрации. Это история про то, как обычная задача «передать человеку файл» бесила меня ровно столько раз, что в итоге я сел и написал своё.

Передать файл и не отдать его половине интернета

Сценарий до боли знакомый: надо скинуть коллеге пароль от сервера, или документ, или дамп базы. Открываешь варианты и тихо вздыхаешь.

WeTransfer и аналоги видят всё, что ты загрузил, по определению. Почта и телеграм оставляют файл лежать в плейнтексте навсегда, на всех серверах по пути. PrivateBin отличный, но это только текст, файл на пару гигабайт туда не положишь. А хочется простого: бросил файл, получил ссылку, и сервер при этом физически не может его прочитать. Причём сервер мой.

В какой-то момент я перестал искать и написал share·me.

Идея на салфетке: ключ кладём в ссылку, серверу не показываем

Браузер генерирует случайный ключ и шифрует файл прямо у тебя на клиенте через AES-256-GCM. А ключ отправляется вот сюда:

https://share.example/d/AbC123#k=<base64-ключ>

Всё, что после #, браузер никогда не отправляет на сервер. Этого нет ни в строке запроса, ни в логах сервера, ни в access-логах прокси, который ты воткнул спереди. Ссылка несёт ключ, а сервер видит только шифротекст, включая имена файлов. Вот и весь фокус, до неприличия простой.

Не хочешь ключ в ссылке? Есть парольный режим: ключ выводится через Argon2id (фолбэк PBKDF2). Неверный пароль просто не проходит серверную авторизацию, а она с rate-limit, так что офлайн-перебора нет.

Нюанс, про который туториалы скромно молчат: 5 ГБ в память не положишь

Любой гайд «зашифруй файл через WebCrypto» вызывает encrypt(весь_файл). Попробуй так с загрузкой на 5 ГБ, и вкладка ловит OOM. Реальные файлы надо стримить.

Поэтому крипто-пакет использует сегментированный AES-256-GCM STREAM: файл режется на чанки, каждый шифруется на HKDF-производном подключе со счётчиком-нонсом. Две вещи, на которых я споткнулся и которые стоит назвать вслух:

  • Нонсы чанков должны быть детерминированными и упорядоченными. Иначе ты не расшифруешь поток, который не буферизовал целиком. Счётчики, а не случайные нонсы.

  • AES-GCM не key-committing. Один шифротекст можно подделать так, что он чисто расшифруется под двумя разными ключами. Для сервиса обмена файлами это реальная мина, поэтому есть key-committing заголовок, привязывающий шифротекст ровно к одному ключу.

Браузер ↔ API стримят напрямую, Rust-сервис не держит файл в памяти целиком.

Архитектура

Браузер (AES-256-GCM на клиенте)
   │
   ▼
Traefik ──/api/*──► Rust / axum API ──► блобы (диск или S3) + метаданные (SQLite/Postgres)
   └─────/*──────► Next.js BFF

Один origin через Traefik, а значит, никакого CORS. Тонкий BFF на Next.js (Server Actions) держит owner-токен каждого дропа в httpOnly-cookie; большие блобы идут мимо него, прямо в API. Срок жизни, лимит скачиваний, burn-after-reading и time-lock enforced на сервере, клиент не сможет их обмануть.

Поднять у себя

git clone https://github.com/onokashino/share-me.git && cd share-me
docker compose up --build   # http://localhost

Указал DOMAIN + ACME_EMAIL, и Traefik сам выпустит сертификат Let’s Encrypt. Готовые образы лежат на ghcr.io. Хватает 1 vCPU / 1 ГБ RAM: упирается в диск и трафик, а не в процессор.

Одна честная оговорка: стороннего аудита пока нет. Криптография специально вынесена в один небольшой пакет с минимумом зависимостей, чтобы её реально можно было прочитать за один присест. Буду рад, если кто-то знающий поищет в ней дыры. Лицензия AGPL-3.0.

Комментарии (5)


  1. gerbert_MX
    09.06.2026 05:53

    а зачем вообще ключ?

    я себе еще давным давно сделал для хоста систему, что позволяет отдавать файлы или по фиксированному названию или сгенерированная случайная строка. При этом оба варианта можно ограничить как сроком выдачи, так и лимитом на загрузки после которого файл так же пропадает из общего доступа

    Это к тому что главная защита это уникальная ссылка, а далее уже файл доступен как обычно любым способом хоть с консоли скачать. Если сервер ваш то проблем компрометации нет. Даже если есть то навернуть внуренее шифрование и все.


    1. MountainGoat
      09.06.2026 05:53

      главная защита это уникальная ссылка

      И куча собеседников с телеметрийными расширениями, которые шлют все ссылки каким-то ботам на анализ.


      1. gerbert_MX
        09.06.2026 05:53

        Потому и поддержка лимитов на срок или на количество загрузок

        в любом случае от ссылки с ключом оно ничем не отличается, кроме оверхеда на шифрование со стороны сервера


  1. wii
    09.06.2026 05:53

    А как залить и скачать через curl, если под рукой только консоль? Но с # частью для ключа, признаюсь, до неприличия просто впечатлен :)


  1. persona
    09.06.2026 05:53

    Странно что не нашли. Есть такие шарилки и думаю даже не одна. На работе ставили и использовали.