Понимаю, что заголовок кликбейтный, но именно это произошло со мной. В @RuStore написал некий "владелец формата файла", показал "лицензию" у себя на сайте, где написано, что только он может читать файлы такого формата, а другие должны просить его разрешения. Этого хватило, чтобы заблокировать мне приложение, в котором чтение этого формата - лишь малая часть функционала.
![Вот что остается от вашего приложения, вы теряете весь доступ к данным, у пользователей перестают работать покупки, Вот что остается от вашего приложения, вы теряете весь доступ к данным, у пользователей перестают работать покупки,](https://habrastorage.org/getpro/habr/upload_files/ac9/04b/b8f/ac904bb8fd1877dc87d1deca049295ca.png)
А теперь подробнее:
Предыстория
Летом 2020 года я начал разработку приложения для вышивки крестом. Побудило меня к этому то, что тут была монополия одного платного приложения, которое довольно странно работало, а еще его разработчик отличался особым общением с пользователями, особенно с теми, кто оставил отрицательный отзыв. Я решил, что смогу сделать намного лучше.
Для создания такого приложения мне нужно было научится читать файлы, созданные в программе редактирования схем для вышивки. Естественно, никакой спецификации на такие файлы нет. А сами файлы содержат бинарные данные. На мои запросы спецификации, я либо не получил ответ (одна программа давно заброшена), либо получил отказ.
В порядке интереса я даже написал на почту тем разработчикам-конкурентам, могут ли они поделиться информацией, но никакого ответа не получил.
В целом изучить файл - это не такая сложная задача. Вы создаете схему, сохраняете файл, затем делаете минимальное изменение в редакторе и сохраняете еще один файл. Затем изучаете разницу в этих файлах, таким образом восстанавливая их структуру.
![Во втором файле я изменил ширину схемы с 10 на 11 крестиков. Таким образом нашел место в файле, отвечающее за этот размер. Также в 010 Editor есть мощная система шаблонов с которой удобно строить структуру файла, но это тема отдельной статьи. Во втором файле я изменил ширину схемы с 10 на 11 крестиков. Таким образом нашел место в файле, отвечающее за этот размер. Также в 010 Editor есть мощная система шаблонов с которой удобно строить структуру файла, но это тема отдельной статьи.](https://habrastorage.org/getpro/habr/upload_files/eab/74c/bfa/eab74cbfa4dd4139b0dbfecacc3faa24.png)
Это все работает до тех пор, пока данные записаны напрямую в файл. Если данные запакованы, зашифрованы или еще что-то, то тут нам надо уже смотреть сам код. Благо статья 1280 ГК РФ нам это позволяет:
3. Лицо, правомерно владеющее экземпляром программы для ЭВМ, вправе без согласия правообладателя и без выплаты дополнительного вознаграждения воспроизвести и преобразовать объектный код в исходный текст (декомпилировать программу для ЭВМ) или поручить иным лицам осуществить эти действия, если они необходимы для достижения способности к взаимодействию независимо разработанной этим лицом программы для ЭВМ с другими программами, которые могут взаимодействовать с декомпилируемой программой
Вооружаемся любимым дизассемблером и ищем как же именно данные записываются в файл.
![Тут чтение данных из файла зависит от версии программы, в которой они были созданы. Тут чтение данных из файла зависит от версии программы, в которой они были созданы.](https://habrastorage.org/getpro/habr/upload_files/8df/c5b/6e3/8dfc5b6e3afcce3ae81716c563d6e86b.png)
Таким образом я изучил форматы схем двух самых популярных у дизайнеров программ и на этом остановился.
Но многие дизайнеры, не хотели бы отдавать "исходник" из редактора покупателям. Для них я сделал конвертер уже в "свой" формат, в котором оставлены только необходимые данные. А также в качестве небольшой защиты - добавил "шифрование" аккаунтом почты пользователя, которая указана на устройстве. таким образом такой файл расшифруется там, где на устройстве совпадёт аккаунт с ключом шифра. Примитивно, но в целом работает. К слову, такой же "свой" формат был и у конкурентов, но без защиты для определенного пользователя.
Завязка
В один прекрасный день, мне пишут, что мой формат "взломали", программа конкурентов открывает схемы в этом формате, и там можно вручную указать аккаунт для расшифровки. Я не понял в чем был смысл этого, но решил, что тогда надо и себе добавить чтение файлов того приложения, о чем давно просили пользователи, которые хотели вышивать купленные ими схемы в том формате, но в моем приложении. Сказано - сделано.
Я был готов снова провести пару недель в HEX редакторе и отладчике, однако все оказалось куда проще:
Открываем файл в редакторе и видим заголовок ZIP архива "PK"
![Первый взгляд на файл Первый взгляд на файл](https://habrastorage.org/getpro/habr/upload_files/187/3b9/02c/1873b902c59ebc5ae7b7d178a994e624.png)
Распаковываем как ZIP, получаем список файлов и снова смотрим на один из них в HEX редакторе
![Файлы в архиве Файлы в архиве](https://habrastorage.org/getpro/habr/upload_files/e88/788/705/e88788705418b65e8f44b8fd9956eac8.png)
![Очень похоже, что закодировано Base64 Очень похоже, что закодировано Base64](https://habrastorage.org/getpro/habr/upload_files/7bd/669/fe0/7bd669fe066307d8f91d9c4c45f24560.png)
Пробуем декодировать в онлайн декодере:
![Декодированный Base64 Декодированный Base64](https://habrastorage.org/getpro/habr/upload_files/3ea/5d9/b31/3ea5d9b31393ca9e9323fd9fdf8d8135.png)
Уже похоже на какие-то данные, но зашифрованные. Тут нам уже надо будет заглянуть в бинарный файл программы.
Я изучаю версию для Android, так как apk файл можно скачать с сайта приложения. Приложение мультиплатформенное, значит ядро будет написано на чем-то вроде С++ и лишь небольшая часть на java.
Поскроллив немного дизассемблированный код нативной библиотеки, я натыкаюсь на такой псевдокод:
![Подозрительный псевдокод Подозрительный псевдокод](https://habrastorage.org/getpro/habr/upload_files/3d9/b06/707/3d9b0670750fed476dc07143cd3121ef.png)
Значит в Java коде есть некая функция Decode, куда передаются 2 строки, очень похожие на некий ключ.
Переходим в Android Studio и смотрим байткод этого класса, видим здесь декодирование Base64, а затем стандартное шифрование AES.
![Байткод функции расшифровки Байткод функции расшифровки](https://habrastorage.org/getpro/habr/upload_files/fac/d5c/58e/facd5c58e9cd1cd0c1f38baa4d5a9aac.png)
Гуглим работу в Java с
Base64.decode
SecretKeySpec
IvParameterSpec
Cipher
Быстро набрасываем код и смотрим результат в отладчике:
![Расшифрованные данные Расшифрованные данные](https://habrastorage.org/getpro/habr/upload_files/133/d3b/d4f/133d3bd4f9a930376f09797329ee759c.png)
Дальше уже проанализировать XML не составило никакого труда. Формат был добавлен, пользователи счастливы. Дата 14 февраля 2022 года.
Кульминация
В октябре 2022 года я добавляю свое приложение в @RuStore Прохожу огромное количество проблем с монетизацией, чтобы пользователи и РФ могли дальше легально делать покупку в приложении не каким-то левым способом, а в официальном магазине приложений РФ.
2 Мая 2023 - приложение было заблокировано без уведомлений, на мой запрос в Рустор я получил ответ:
Приложение было заблокировано по требованию правообладателей приложения Cross Stitch Saga. Представители сообщили, что вы добавили проприетарный формат их приложения .saga и разрешили его чтение без разрешения правообладателя.
Тогда Рустор приняли мои доводы о том, что формат файла не является объектом авторского права и его чтение не является нарушением, восстановили приложение, ответили:
Также хотим подсветить, что мы продолжим разбираться в юридической стороне ситуации. Если у нас появятся дополнительные вопросы, мы с вами свяжемся.
12 Мая 2023 поступило письмо:
Настоящим сообщаем, что на наш адрес поступила претензия в связи с незаконным использованием в рамках приложения Cross Stitch Paradise формата SAGA, исключительные права на который по утверждению заявителя принадлежат ему.
Контакты заявителя: email адрес. В связи с поступлением претензии просим Вас в течение 5 (пяти) рабочих дней устранить нарушение или связаться с заявителем для урегулирования спора.При наличии законных оснований использования формата SAGA предоставить соответствующие доказательства, например: согласие правообладателя на использование формата SAGA, лицензионный договор на использование формата SAGA или иные доказательства.В случае непредоставления подтверждения устранения нарушения, урегулирования спора с заявителем или документов, подтверждающих законность использования формата SAGA в рамках приложения Cross Stitch Paradise, мы будем вынуждены заблокировать приложение Cross Stitch Paradise в RuStore.
В этой претензии не содержится:
контактных данных адресанта, только электронная почта, по которой нет никакой информации о заявителе
перечисления объектов авторского права с подтверждением авторства
ссылок на патенты
ссылок на лицензионный договор
После этого была переписка с кем-то по адресу, который был указан как контактный:
Файл SAGA является архивом с зашифрованными данными алгоритмом AES128 https://ru.wikipedia.org/wiki/AES_(стандарт_шифрования), для получения доступа к которым используются ключи шифрования, являющиеся частью исходного кода приложения Cross Stitch Saga (эти ключи хранятся исключительно в коде приложения Cross Stitch Saga и в свободный доступ не выкладывались). Получить эти ключи подбором данных между исходным файлом схемы и схемой в формате SAGA или иным подбором не представляется возможным без реверс-инжиниринга приложения Cross Stitch Saga. По подсчетам EETimes на подбор ключей для алгоритма AES128 уйдет миллиард лет с использованием суперкомпьютера https://www.eetimes.com/how-secure-is-aes-against-brute-force-attacks/ Возникает вопрос, требующий разъяснения: каким образом разработчик Cross Stitch Paradise получает данные из файлов SAGA не используя ключи шифрования, которые являются частью исходного кода приложения Cross Stitch Saga?
Мой ответ:
Ключи "i0dLlD..." и "00RW..." не содержат в себе какого-то кода или алгоритма и служат просто для расшифровки XML данных стандартным(!) методом шифрования "AES/CBC/PKCS7Padding". Эти данные были получены в результате исследования формата файла и того, как с ним взаимодействует приложение, что является абсолютно законным с точки зрения Гражданского кодекса, статья 1280: http://www.consultant.ru/document/cons_doc_LAW_64629/3cbc9e0590122df6ade6baf1d39f9ee34411c24a/
Ответ Сага:
Ключи шифрования хранятся в скомпилированном коде приложения (написанном на С++), а не в открытом виде или в каком-то файле. Ключи шифрования также не содержатся в формате SAGA. В данном тезисе разработчик Cross Stitch Paradise подтверждает факт реверс-инжиниринга приложения Cross Stitch Saga.
Рекомендуем разработчику Cross Stitch Paradise убрать из своего приложения использование этих ключей шифрования, применяемых для чтения файлов формата SAGA, а также воздержаться от распространения этих ключей шифрования третьим лицам или в свободный доступ.
Уже тут заявитель понял, что версия с "проприетарный формат" не сработает и переключился на "ключи шифрования"
Мой ответ:
Так как все данные получены законным путем, никакие авторские права не нарушены, то рекомендую прекратить все нападки на приложение Cross Stitch Paradise.
На этом этапе юристам RuStore уже должно быть понятно, что некий представитель Cross Stitch Saga пытается хоть как-то оправдать "уникальность" своего формата и уже переходит к рекомендациям, а не требованиям.
В реальности же мы имеем:
архив ZIP - открытая спецификация
в нем файлы XML - вообще текстовая структура
кодированы алгоритмом Base64 - открытая спецификация
зашифрованы алгоритмом AES - открытый стандарт шифрования
Весь код расшифровки - вызовы стандартных процедур из библиотеки Java
Никакого уникального алгоритма или изобретения, который можно было бы запатентовать - тут нет.
Никакого взлома или глубокого реверс инжиниринга для получения ключей не нужно, их просто видно как строки.
А пункт 3. статьи 1280 ГК РФ нам прямо говорит:
Пользователь вправе декомпилировать ПО, если это необходимо для достижения способности к взаимодействию независимо разработанной этим лицом программы для ЭВМ с другими программами, которые могут взаимодействовать с декомпилируемой программой.
То есть Закон РФ мне напрямую разрешает делать реверс-инжиниринг, чтобы взаимодействовать с файлами других программ! И никакое "Лицензионное соглашение" не вправе это запретить.
Со всеми этими обоснованиями согласился мой юрист. На этом я надеялся, что конфликт исчерпан полностью. Никаких других данных не было, 5 дней прошло.
30 мая 2023 - снова блокировка без уведомления:
Приложение было заблокировано по требованию правообладателя. В случае несогласия вы можете обратиться напрямую к правообладателю для урегулирования спора: email адрес
Заключение
На этом моменте мой адекватный диалог с @RuStore остановился, на свои запросы об:
официальной претензии с контактами заявителя, а не просто электронной почтой
хоть каких-то доказательств наличия прав у заявителя
хоть каких-то доказательств нарушения законов моим приложением
Я не получил ответов, только "мы разблокируем ваше приложение, если правообладатель отзовёт претензию. Все ваши обращения будут закрыты." Естественно такой "правообладатель" добился блокировки конкурента и ничего не будет отзывать. При этом его самого нет в RuStore, а в Google Play никаких претензий нет.
Получаем ситуацию, что кто угодно у себя на сайте пишет, что только его приложение может открывать формат mp3, связывается с RuStore по email и требует заблокировать все плееры в магазине - получает удовлетворение своих требований. После этого игнорирует все письма на их адрес.
В похожей ситуации, насколько мне известно, Google делает так - снимает приложение с публикации и ждет ответ. Если обвиняемый уверен в своей правоте - то контент восстанавливается, а заявителю предлагается идти в суд и далее предоставить решение суда.
Даже на предложение убрать чтение этого формата на время разбирательств я также получил отказ, вот тебе и отечественный магазин с поддержкой российского ПО. RuStore пошел навстречу и разрешил опубликовать билд без этого формата.