#Tool.SafeSource prototype (Crypt/Decrypt)

dev-linux
Ivan Maslov 4 years ago
parent 4d11387fb7
commit caeab37fbd

@ -0,0 +1,64 @@
import os, random, struct
from Crypto.Cipher import AES
def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
""" Шифрует файл используя AES (режим CBC) с
заданным ключом.
key:
Ключ шифрования - строка длиной
16, 24 или 32 байта. Более длинные ключи
более безопасны.
in_filename:
Имя входного файла
out_filename:
Если None, будет использоваться «<in_filename> .enc».
chunksize:
Устанавливает размер фрагмента, который функция
использует для чтения и шифрования файла.Большие
размеры могут быть быстрее для некоторых файлов и машин.
кусок (chunk) должен делиться на 16.
"""
if not out_filename:
out_filename = in_filename + '.enc'
iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(16))
iv = iv.encode('utf8')[0:16]
encryptor = AES.new(key, AES.MODE_CBC, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
while True:
chunk = infile.read(chunksize)
print(chunk)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += b' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
def decrypt_file(key, in_filename, out_filename=None, chunksize=24*1024):
""" Расшифровывает файл, используя AES (режим CBC) с
заданным ключом. Параметры аналогичны encrypt_file,
с одним отличием: out_filename, если не указано
будет in_filename без его последнего расширения
(т.е. если in_filename будет 'aaa.zip.enc', тогда
out_filename будет 'aaa.zip')
"""
if not out_filename:
out_filename = os.path.splitext(in_filename)[0]
with open(in_filename, 'rb') as infile:
origsize = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
iv = infile.read(16)
decryptor = AES.new(key, AES.MODE_CBC, iv)
with open(out_filename, 'wb') as outfile:
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
outfile.write(decryptor.decrypt(chunk))
outfile.truncate(origsize)

@ -0,0 +1,28 @@
import pyautogui # Enter password window
import hashlib # Create hash of the key
import tkinter #tkinter
from tkinter import filedialog
from . import Crypter
# Create process run
def Run():
# Step 1 - select folder to crypt
lStep_1_TkinterRoot = tkinter.Tk()
lStep_1_TkinterRoot.withdraw()
#lStep_1_FolderPath = filedialog.askdirectory(parent=lStep_1_TkinterRoot,title='Please select a source code directory to crypt')
# Step 2 - set password to crypt
lKeyHashStr_1 = hashlib.sha256(pyautogui.password('Please enter the key to protect source code').encode("utf-8")).digest()
print(lKeyHashStr_1)
lKeyHashStr_2 = hashlib.sha256(pyautogui.password('Please repeat the key to protect source code').encode("utf-8")).digest()
print(lKeyHashStr_2)
if lKeyHashStr_1 == lKeyHashStr_2:
print("Passed - do AES encryption")
from Crypto.Cipher import AES
#Crypter.encrypt_file(lKeyHashStr_1, "c:\\test.png", "c:\\test.enc")
Crypter.decrypt_file(lKeyHashStr_1, "c:\\test.enc", "c:\\testEnc2.png")
#IV = 16 * '\x00' # Вектор инициализации: обсуждается позже
#mode = AES.MODE_CBC
#encryptor = AES.new(lKeyHashStr_1, mode, IV=IV)
#text = "Text to be crypted!"
#ciphertext = encryptor.encrypt(text)

@ -0,0 +1,135 @@
#coding=utf-8
import os
import sys
import imp
import base64
EXT = '.b64'
# How to run
# sys.meta_path.append(Base64Importer(root_pkg_path))
# Init cryptographer
def CryptographerInit(inFolderPath):
print(1)
sys.meta_path.append(Base64Importer(inFolderPath))
#===============================================================================
class Base64Importer(object):
"""Служит для поиска и импорта python-модулей, кодированных в base64
Класс реализует Import Protocol (PEP 302) для возможности импортирования
модулей, зашифрованных в base64 из указанного пакета.
"""
#---------------------------------------------------------------------------
def __init__(self, root_package_path):
self.__modules_info = self.__collect_modules_info(root_package_path)
#---------------------------------------------------------------------------
def find_module(self, fullname, path=None):
"""Метод будет вызван при импорте модулей
Если модуль с именем fullname является base64 и находится в заданной
папке, данный метод вернёт экземпляр импортёра (finder), либо None, если
модуль не является base64.
"""
if fullname in self.__modules_info:
return self
return None
#---------------------------------------------------------------------------
def load_module(self, fullname):
"""Метод загружает base64 модуль
Если модуль с именем fullname является base64, то метод попытается его
загрузить. Возбуждает исключение ImportError в случае любой ошибки.
"""
if not fullname in self.__modules_info:
raise ImportError(fullname)
# Для потокобезопасности
imp.acquire_lock()
try:
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
mod.__file__ = "<{}>".format(self.__class__.__name__)
mod.__loader__ = self
if self.is_package(fullname):
mod.__path__ = []
mod.__package__ = fullname
else:
mod.__package__ = fullname.rpartition('.')[0]
src = self.get_source(fullname)
try:
exec(src) in mod.__dict__
except:
del sys.modules[fullname]
raise ImportError(fullname)
finally:
imp.release_lock()
return mod
#---------------------------------------------------------------------------
def is_package(self, fullname):
"""Возвращает True если fullname является пакетом
"""
return self.__modules_info[fullname]['ispackage']
#---------------------------------------------------------------------------
def get_source(self, fullname):
"""Возвращает исходный код модуля fullname в виде строки
Метод декодирует исходные коды из base64
"""
filename = self.__modules_info[fullname]['filename']
try:
with open(filename, 'r') as ifile:
src = base64.decodestring(ifile.read())
except IOError:
src = ''
return src
#---------------------------------------------------------------------------
def __collect_modules_info(self, root_package_path):
"""Собирает информацию о модулях из указанного пакета
"""
modules = {}
p = os.path.abspath(root_package_path)
dir_name = os.path.dirname(p) + os.sep
for root, _, files in os.walk(p):
# Информация о текущем пакете
filename = os.path.join(root, '__init__' + EXT)
p_fullname = root.rpartition(dir_name)[2].replace(os.sep, '.')
modules[p_fullname] = {
'filename': filename,
'ispackage': True
}
# Информация о модулях в текущем пакете
for f in files:
if not f.endswith(EXT):
continue
filename = os.path.join(root, f)
fullname = '.'.join([p_fullname, os.path.splitext(f)[0]])
modules[fullname] = {
'filename': filename,
'ispackage': False
}
return modules

@ -0,0 +1,21 @@
#argv 0 = "RUN"/"CREATE"
#Import parent folder to import current / other packages
#########################################################
import sys
import subprocess #start process async
import os #path, run, remove
import time #timer
import importlib
#lFolderPath = "\\".join(__file__.split("\\")[:-4])
lFolderPath = "/".join(__file__.split("/")[:-4])
sys.path.insert(0, lFolderPath)
from pyOpenRPA.Tools.SafeSource import DistrRun
from pyOpenRPA.Tools.SafeSource import DistrCreate
#Mode RUN
if sys.argv[1].upper() == "RUN":
DistrRun.CryptographerInit("")
#Mode CREATE
if sys.argv[1].upper() == "CREATE":
DistrCreate.Run()
pass

@ -0,0 +1,4 @@
cd %~dp0..\..\Sources
copy /Y ..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe ..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_SafeSource.exe
..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_SafeSource.exe -m pyOpenRPA.Tools.SafeSource "CREATE"
pause >nul

@ -0,0 +1,4 @@
cd %~dp0..\..\Sources
copy /Y ..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe ..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_SafeSource.exe
..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_SafeSource.exe -m pyOpenRPA.Tools.SafeSource "Run"
pause >nul
Loading…
Cancel
Save