Всем привет! Вот задался себе вопросом - по какому принципу работает серийный/лицензионный ключ. А так же KeyGen этих ключей. Не, я не хочу ничего ломать и ничего изобретать, просто заинтересовало, возможно сделаю как "винт" и прикручу к какой-нибудь программе. В инете пишут, есть некие алгоритмы шифровки и дешифровки, но их я не нашел :/ Может кто-нибудь вкраце может пояснить что да как? Заранее спасибо!
алгоритмов великое множество. Например, можно сделать привязку ключа с серийным номерам какого то оборудования. В этом случае при переносе программы на другое железо, или замена одной из компонент, на основе номеров которых строился общий серийный номер, приведет к необходимости покупки новой лицензии. А сам ключ в этом примере - просто зашифрованная структура из имени владельца и того же общего серийного номера. Программа при запуске заново вычисляет общий номер и сверяет его с указанным в лицензии. Если совпали - профит - позволит продолжить работу. Кейген работает на том же принципе, только в обратную сторону. Зная, как строится номер лицензии к программе, вычисляет необходимый номер, запрашивает на какого пользователя делать лицензию и создает итоговую структуру, которую подсовываем к оригинальной программе и "не платим разработчику". Это принцип с привязкой к оборудованию. Бывает еще просто последовательность символов, такой ломается проще менее надежен по определению.
а что он запрашивает у компьютера, Mac-адрес? или есть ещё что-то индивидуальное у компьютера? И как можно запросить у компьютера МАС-адрес через С++? Где про это можно почитать?
Серийный номер процессора, жесткого диска, да практически любой железки в компе... А вот MAC-адрес скорей всего не используют, т.к. его можно изменить программно.
можно и МАС адрес, можно и серийные номера процессора/мат.платы/жесткого диска Для Arduino можно и ATSHA204 чип использовать http://www.cracklab.ru/pro/cpp.php?r=network&d=zdrt21
Но я попробовал сделать по своему, конечно толку ноль от такого серийника, но зато очень хорошо защищает от пользователей "начального уровня" пример серийника: p3t5-zk65-7 "p3t5" - часть X "7" - часть Y "zk65" - программная часть (если этого требует программа, например доступ "root" или "user", некая "активация дополнения программы" и т.п) Расчет идет по такому принципу: X - Y = 260 Программная часть в проверку серийника не идёт. Если хотите: могу код выложить
Обратимся к теории: весь "внутренний мир" компьютера состоит из "0" и "1". Следовательно все в компе "0" и "1". Тогда почему бы и не вычесть? Но это очень глубоко, я обратился к ACSII таблице, где у каждого символа в системе (их 255) есть свой номер. т.е сначало в "приёмнике" мы весь серийник ( а он у меня в массиве key[] типа char) конвертируем в численный вид (тип int), вычисляем, проверяем, "if(md2==260){Правильно!}", с кейгеном наоборот.
Проверялка: Код (Text): #include <iostream> #include <string.h> #include <conio.h> #define GEN_MD 260 //Сумма, которая получится в результате вычислений. using namespace std; char str[255] = {0}; char ch; char* p = str; int buff[] ={0}; int main() { cout << "LKE, press your licence key: " << endl; //*********************************************** memset(str, 0, 255); //Ввод серийника p = str; while (cin.get(ch) && isalnum(ch)) *p++ = ch; //*********************************************** //=============================================== for(int q=0; q<9; q++) //конвертация из char в int { buff[q] = str[q]; } //=============================================== buff[16] = buff[0] + buff[1] + buff[2] + buff[3] - buff[8]; //Вычисляем по формуле. if(buff[16] == GEN_MD) { //Accept cout << endl << "Accept!" << endl; while(true) { //Выполнение программы... } } else { //ERROR, не лицензионный! cout << endl << "Invalid key!" << endl << "Reboot programm, and reenter your key..." << endl << "Press any key, to out programm..."; getch(); return 0; //cout << "MD = " << buff[16] << endl; //cout << endl << buff[0] << " " << buff[1] << " " << buff[2] << " " << buff[3] << " - " << buff[8] << endl; } //=============================================== } КейГен: Код (Text): #include <iostream> #include <string.h> #include <stdlib.h> #include <conio.h> #include <time.h> #define GEN_Type 260 //Сумма, которая должна получиться #define PER_Type 2 //permission using namespace std; char key[] = {0}; int buff[] = {0}; int md1[2] = {0}; int md2[2] = {0}; int x[1] = {0}; void aces(int xx) //Permission to User { switch(xx) { case 0: { cout << "root"; break; } case 1: { cout << "admin"; break; } case 2: { cout << "user"; break; } default: cout << "error"; break; } } int main() { cout << "Press 'g' - to generate key, press 'q' - to exit programm, 'i' - info" << endl; while(true) { if(getch() == 'g') { //X-Y=260; //**************************************** srand(time(0)); x[1] = rand() % 9 + 48; //от 0 до 9 buff[8] = x[1]; //вычитаемое Y md1[1]=GEN_Type+x[1]; //MD1 - сумма ключа Х, которая должна получиться //=== //Генерация ключа X srand(time(0)); buff[0] = rand() % 16 + 97; srand(time(0)); buff[1] = rand() % 9 + 48; buff[10] = 97; srand(time(0)); buff[3] = rand() % 7 + 48; //=== md2[1] = md1[1] - buff[0] - buff[1] - buff[10] - buff[3]; //MD2 - Проверка, сравнение с md1 buff[2] = buff[10] + md2[1]; //Сливаем остаток в 3-ий символ части Х //Конвертация из int в char. key[0] = buff[0]; key[1] = buff[1]; key[2] = buff[2]; key[3] = buff[3]; key[4] = 'u'; key[5] = 'p'; key[6] = '8'; key[7] = '0'; key[8] = x[1]; //**************************************** cout << "================" << endl; cout << "MD = " << md1[1] << "/" << md2[1] << endl; //Проверка cout << "permission: "; aces(PER_Type); cout << endl << endl; cout << "Key: "; for(int i=0; i<9; i++) cout << key[i]; cout << endl; cout << "================" << endl << endl; } if(getch() == 'i') { cout << endl; cout << "---------------" << endl << "KeyGen v1.4" << endl << "---------------" << endl; } if(getch() == 'q') { break; break; } } return 0; } Немного о кейгене: он не совершенен, его следует доработать... В него я встроил три режима пользователей: root, admin, user. После ввода пользователя, нажимаете "g", он вам генерирует ключ. Если в строке MD второе число отрицательное - заново нажмите на "g", оно должно быть положительное, иначе возможна ошибка в ключе. Потом я автоматизирую этот процесс.. Проверял на Win7 Ultimate x64
Читайте как [аски] и не будете путать. p.s. ИМХО, не делом вы занимаетесь. За применение программной защиты в FOSS/OSHW черные метки выдают
OSHW не запрещено использовать в коммерческих проектах, а комерческий код надо защищать. Нигде не написано, что если железо опенсорсное, то оно не может нести в себе проприетарный код. Так же можно взять плату ардуино и вытереть программатором загрузчик, залить свой - вот и всё, железо опенсорс, прошивка проприетарная