Как защитить апдейтер программы от компроментации сервера?
Есть типичная задача, софт получает обновления с сервера обновлений. Сейчас все сделано просто - обновления загружаются по HTTP протоколу, запакованные ZIP-ом. Некоторые апдейты содержат исполняемые EXE/DLL файлы. Сейчас задумались, что в случае компроментации сервера обновлений , можно наделать бед всем нашим клиентам.
Каким образом правильно организовать работу апдейтера , чтобы он мог отличить свои апдейты от чужих?
Насколько я понимаю, здесь нужно или зашифровать файлы апдейта так, чтобы апдейтер мог их расшифровать неким ключом , при помощи которого нельзя обратно зашифровать другие данные, вытащив этот ключ из программы. Или использовать какую-то цифровую подпись, встраиваемую в файлы на сервере и проверяемые апдейтером.
Мне больше нравится первый вариант, но какой алгоритм выбрать. Мне нужно будет шифровать файлы открытым ключом, а закрытый вшить в апдейтер, но, насколько я понимаю, вытащив этот закрытый ключ из программы, можно сделать открытый и вся защита теряет смыл.
Второй вариант можно првоернуть с использованием gpg , но нам бы хотелось обойтись без сторонних утилит.
Подскажите, как правильнее организовать весь процесс? Решение должно быть встраиваемым , без использования сторонних утилит. Заранее спасибо за помощь.
А что по поводу того, чтобы шифровать закрытым ключом, а в апдейтер зашить открытый. Ведь в моей схеме это решение будет работать так, как я хочу, верно?
Восстановление одного из ключей пары по другому - задача, требующая для серьезных ключей (4096 бит и далее) колоссальных временных затрат.
На самом деле, вам нужно завести хороший публичный сертификат SSL и использовать SSL для передачи обновлений. Весь необходимый функционал реализован в SSL:
-Подтверждение того, что приложение соединилось с легитимным сайтом
-Защита от MiTM путем подмены сайта.
-Защита передаваемой информации.
В программу ничего встраивать не нужно, поэтому и украсть из нее какой-либо ключ будет невозможно.
В криптографии следует использовать сторонние утилиты, так как реализовать качественную защиту крайне сложно.
Спасибо, ваши замечания по поводу проверки легитимности сайта важны, они , однако в случае взлома самого сервера и подмены самих файлов это не спасет, апдейтер вед подключится к легитимному серверу. А вот нужно, чтобы он понял, что файлы , которые он качает, чужие. Что-то вроде того, как организованы репозитарии linux.
А по поводу восстановления открытого ключа из закрытого , вот в мануале для ssh-keygen есть опция
-y This option will read a private OpenSSH format file and print an OpenSSH public key to stdout.
Или я не правильно понимаю и открытый ключ просто хранится в закрытом и таким образом извлекается, а не генерится из закрытого?
Ajex: А какая вам разница генерируется он или хранится? Открытый он на то и открытый, что вы можете смело раздавать его всем злоумышленникам. Отрытым можно только зашифровать данные.
К расшифровке он отношения не имеет.
Правильно , закрытый будет использоваться для расшифровки, но он будет встроен в апдейтер, т.е. считай он в руках злоумышленника, вместе с сгенерированным из него открытым. А значит взломав сервер, они смогут подменить обновления.
Из открытого это понятно, я говорил о том, что из закрытого можно получить открытый! Отсюда мне не подходит вариант шифрования открытым ключом. Вроде ниже я нашел правильное решение с подписью закрытым ключом и проверкой открытым.
Ajex: Прочитайте внимательно раздел про ЭЦП. При использовании RSA для ЭЦП вычисление подписи выполняют закрытым ключом, который хранится у вас, даже не на раздающем сервере. Проверку подписи выполняют открытым ключом.
Вот нашел вроде бы такое решение:
Создаем подпись приватным ключом (на свой стороне) , заливаем signature MyFile.sign и MyFile.Dat
openssl dgst -sha256 -sign private_key.pem -out MyFile.sign MyFile.dat
Приватный ключ хранится у нас, публичный зашивается в апдейтер. Таким образом злоумышленник даже проникнув на сервер обновлений не сможет подписать файлы, т.к. апдейтер не пропустит их.
Тут сходу решаются и остальные проблемы с подменой сервера , mitm и прочим.
Вы защищаете передаваемые данные или сам сервер?
Если первое - переходите на SSL соединение и всё. На сервере https, на клиенте проверка серта средствами OS.
Если нужна защита сервера - то шифрование диска, вход по смарт -карте и тд.
Защищаем сами обновления, а не трафик. Т.е. если в файл на сервере зашить трояна, его получат и , соответственно, запустят все наши клиенты, масштаб трагедии сложно описать. Вот нужно этого избежать любой ценой, чтобы даже в случае взлома сервера обновлений, это никак не отразилось на наших клиентах.
Ajex: тогда шифрование сервера, механика проверки обновлений, через например подписанный файл с хешами всех файлов, тогда не придётся подписывать ве файлы (что долго и сложно проверять на клиенте), но гарантирует целостность. Ну и например несколько не связанных серверов, скачивание идёт то с одного то с другого.
Но боюсь если ваш сервер взломают - то поиметь любую защиту не составит труда.
Ну подписывать хэши или сами файлы тут не суть сейчас важно, это понятно. Вопрос как правильно это сделать, чтобы файл на сервер мог положить только я и только созданный мной, а апдейтер должен понимать, что он создан именно мной. Тогда даже в случае взлома сервера, злоумышленник ничего не сделает, т.к. он не сможет создать файла (допустим с хэшами), который примет апдейтер как валидный.