Я пишу фрагмент кода C ++, который будет содержать ключ доступа к зашифрованному архиву и не позволять его просматривать до определенной даты в системе Linux.
Полный код ниже (да, это некрасиво и имеет system()
вызов. Я чувствую, что это было необходимо для данной ситуации)
#include <iostream> //cout
#include <ctime> //time_t, time()
#include <cstdlib> //system()
#include <unistd.h> //getuid()
using namespace std;
int main () {
//updates the system clock and catches the exit code; must be 0 to proceed
int tcheck = system ("ntpd -q -I pool.ntp.org");
//checks updated time against set timestamp (11/20/16 @ 12 PM) and gives or denies access to key respectively
if ((tcheck == 0) && (getuid() = 0)) {
time_t now = time(0);
if (now < 1479661235)
{cout << "It is not yet time.";}
else
{cout << "The key is: a placeholder";}
}
else if (getuid() != 0)
{cout << "This program must be run as root.";}
else if (tcheck != 0)
{cout << "I think you might be cheating. Let the time server sync and then we'll talk.";}
cin.get();
return 0;
}
Моя проблема заключается в следующем. Ключ должен быть недоступен для пользователя с sudo
привилегии (только с исполняемым файлом в руке), но для такого пользователя было бы относительно легко просто удалить /bin/ntpd
и замените его фиктивной программой, которая возвращает 0 при вызове, тем самым обходя защиту от несанкционированного изменения времени.
Я рассмотрел возможность использования контрольной суммы для обеспечения достоверности программы, но отказался от нее на основании того факта, что промежуточное обновление пакета ntp может также изменить ntpd и сделать ключ недоступным. Я также не могу запросить контрольную сумму для ntpd из диспетчера пакетов, потому что код должен быть переносимым между несколькими дистрибутивами.
У всех вас есть какие-либо идеи относительно того, как еще можно обеспечить достоверность программы (или совершенно разные методы для достижения того же результата)?
PS: Прежде чем вы упомянете об этом, я планирую запутать исходный код, чтобы избежать эксплойтов, так что это не будет проблемой.
Учитывая, что сеть должна быть постоянно доступна для использования программы, перенесите все средства защиты на сервер. На стороне клиента у вас просто будет что-то вроде
wget https://www.yourserver.com/getkey?keyid=xxxxxxxxxxxxxxxxxxxxx
Где параметр для keyid
некоторый идентификатор требуемого ключа (возможно, его SHA1 засолен каким-то секретом, но неважно); Ваш сервер предоставит требуемый ключ, только если время пришло.
Других решений пока нет …