Пользователь
-
Автор темы
- #1
Увидев одну из тем, я понял что этот мир уже не спасти от наплывающих питонистов, поэтому решил показать как надо делать.
Так как у нас будет нормальный код и шифрование данных, мы будем использовать алгоритм RSA.
Нам нужно будет сгенерировать 2 пары, одна для сервер-клиент, вторая для клиент-сервер.
Вместо 1024 можно указать любой размер, чем больше, тем дольше будет работать генерация и алгоритм.
Теперь напишем клиент
А тут будет код сервера, я буду использовать sqlite3 для простоты, кому надо будет перепишет на норм субд
Код есть, но мамкины крякеры, никуда еще не делись, поэтому нам нужно будет защитить код клиента. Мы будем использовать для этого PyArmor, у него есть лишь один недостаток, для защиты большого проекта нужно купить лицензию, но нам сейчас хватит и бесплатной версии.
Для особо внимательных, кто заметил что наш клиент переродился в исполняемом файле: pyarmor использует pyinstaller для упаковки питонячего кода, но даже если супер-крякер777 доберется до распакованной временной папки нашего клиента и декомпилировав pyc файл, открыв исходник он, к его сожалению, увидит лишь это:
Что в итоге мы сделали?
Так как у нас будет нормальный код и шифрование данных, мы будем использовать алгоритм RSA.
Нам нужно будет сгенерировать 2 пары, одна для сервер-клиент, вторая для клиент-сервер.
Вместо 1024 можно указать любой размер, чем больше, тем дольше будет работать генерация и алгоритм.
Python:
pubkey, privkey = rsa.newkeys(1024) # генерируем пару ключей
pickle.dump(privkey, open('key.key', 'wb+')) # сохраняем ключ в файл
Python:
import requests
import datetime
import hashlib
import pickle
import uuid
import json
import rsa
def get_hwid() -> str:
hwid = str(uuid.uuid1(uuid.getnode(), 0))[24:]
hwid_hash = hashlib.sha256(hwid.encode('utf-8'))
return hwid_hash.hexdigest()
def post(url: str, data: dict) -> dict:
client_public_key = pickle.load(open('client_public.key', 'rb'))
server_private_key = pickle.load(open('server_private.key', 'rb'))
encoded = rsa.encrypt(json.dumps(data).encode('utf-8'), client_public_key).hex()
data = {'data': encoded}
response = requests.post(url, data=data)
data = response.json()['data']
decoded = rsa.decrypt(bytes.fromhex(data), server_private_key).decode('utf-8')
return json.loads(decoded)
def get_license(hwid: str) -> bool:
data = post('http://localhost:5000/get_license', {'hwid': hwid})
lic = data['license']
return datetime.datetime.fromtimestamp(lic) > datetime.datetime.now()
hwid = get_hwid()
lic = get_license(hwid)
Python:
from flask import Flask, request
import datetime
import sqlite3
import pickle
import json
import rsa
client_private_key = pickle.load(open('client_private.key', 'rb'))
server_public_key = pickle.load(open('server_public.key', 'rb'))
class Database:
def __init__(self, db_name: str):
self.db_name = db_name
self.initialize()
def initialize(self):
connection = self.get_connection()
cursor = connection.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS users('
'id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,'
'hwid VARCHAR(64),'
'license REAL)')
connection.commit()
cursor.close()
connection.close()
def get_connection(self):
return sqlite3.connect(self.db_name)
def get_license(self, hwid: str) -> datetime.datetime:
connection = self.get_connection()
cursor = connection.cursor()
cursor.execute(f"SELECT license FROM users WHERE hwid='{hwid}'")
(result,) = cursor.fetchone()
cursor.close()
connection.close()
return datetime.datetime.fromtimestamp(result)
def update_license(self, hwid: str, date: datetime.datetime) -> None:
connection = self.get_connection()
cursor = connection.cursor()
cursor.execute(f"UPDATE users SET license={date.timestamp()} WHERE hwid='{hwid}'")
connection.commit()
cursor.close()
connection.close()
def set_license(self, hwid: str, date: datetime.datetime) -> None:
connection = self.get_connection()
cursor = connection.cursor()
cursor.execute(f"INSERT INTO users (hwid, license) VALUES ('{hwid}', {date.timestamp()}")
connection.commit()
cursor.close()
connection.close()
db = Database('database.db')
app = Flask(__name__)
@app.route('/get_license', methods=['POST'])
def get_license():
if request.method == 'POST':
data = request.form['data']
data = json.loads(rsa.decrypt(bytes.fromhex(data), client_private_key))
hwid = data['hwid']
lic = db.get_license(hwid).timestamp()
response = rsa.encrypt(json.dumps({'license': lic}).encode('utf-8'), server_public_key).hex()
return {'data': response}
return '404'
app.run()
Код есть, но мамкины крякеры, никуда еще не делись, поэтому нам нужно будет защитить код клиента. Мы будем использовать для этого PyArmor, у него есть лишь один недостаток, для защиты большого проекта нужно купить лицензию, но нам сейчас хватит и бесплатной версии.
- Устанавливаем pyarmor
- Открываем терминал и переходим в папку нашего клиента
- Пишем
pyarmor pack -e " --onefile" client.py
- Ждем пока закончится магия
- В папке dist будет лежать exe файл нашего клиента
Для особо внимательных, кто заметил что наш клиент переродился в исполняемом файле: pyarmor использует pyinstaller для упаковки питонячего кода, но даже если супер-крякер777 доберется до распакованной временной папки нашего клиента и декомпилировав pyc файл, открыв исходник он, к его сожалению, увидит лишь это:
Python:
from pytransform import pyarmor_runtime
pyarmor_runtime()
__pyarmor__(__name__, __file__, b'\x50\x59\x41\x52\x4d\x4f...', 2)
Что в итоге мы сделали?
- Написали более менее человеческий код
- Защитили исходник
- Использовали СУБД!!!!
- Написали сервер (wow)