import os from datetime import datetime import random import math import base64 import hashlib from Crypto import Random from Crypto.Cipher import AES import rsa import string encoding0 = int(os.environ['encoding']) padding0 = int(os.environ['padding']) encryption_difficulty0 = int(os.environ['encryption_difficulty']) N_days0=int(os.environ['N_days']) User_passcode0=int(os.environ['User_passcode']) power0 = float(os.environ['power']) #path0 = float(os.environ['path']) #publicKey0 = int(os.environ['publicKey']) def seedx(path , User_passcode=User_passcode0, N_days=N_days0, encryption_difficulty = encryption_difficulty0): try: with open(path +'indx.txt') as f: old_day_index = int(f.read()) except: old_day_index = 0 print('no old index was found') #os.environ['old_day_index'] = str(old_day_index) timestamp = datetime.timestamp(datetime.now()) #total number of days since unix time days_span = timestamp/math.factorial(6)/120 + 0.1#*random.random() #first time calculate the days since unix, thae latter randomize the time zone by up to ~7 hours day_index = math.floor(days_span/N_days) seed = int(day_index**power0 + User_passcode) if day_index == old_day_index: # with open('prvt.pem', 'rb') as file: # key_data = file.read() # privateKey = rsa.PrivateKey.load_pkcs1(key_data) with open('pblc.pem', 'rb') as file: key_data = file.read() publicKey = rsa.PublicKey.load_pkcs1(key_data) else: publicKey, privateKey = rsa.newkeys(encryption_difficulty) old_day_index = day_index #save in a folder with open(path +'indx.txt', 'w') as f: f.write(str(old_day_index)) #with open(path +'prvt.pem', 'w') as f: # f.write(privateKey.save_pkcs1().decode('utf-8')) with open(path +'pblc.pem', 'w') as f: f.write(publicKey.save_pkcs1().decode('utf-8')) return {'seed':seed,'publicKey': publicKey} #, 'privateKey': privateKey} def AES_encrypt(User_message,seed, publicKey,encoding = encoding0, padding = padding0): #number conversion to encrypt non-english content User_message_numbered = (int.from_bytes(bytes(User_message, 'utf-16'), "big")) #padding front_padding = ''.join(random.choices(string.digits, k=padding)) #string.ascii_lowercase + back_padding = ''.join(random.choices(string.digits, k=padding)) #string.ascii_lowercase + msg = front_padding + str(User_message_numbered) + back_padding msg_len =len(msg) #total number of charachters in the msg permutation_list = list(range(0,msg_len)) random.seed(seed) random.shuffle(permutation_list) shffled_msg_list = [msg[i] for i in permutation_list] shffled_msg = ''.join(shffled_msg_list) #print(shffled_msg) encMessage = AESCipher(str(publicKey.n)).encrypt(shffled_msg) if encoding == 0: encMessage_int = encMessage elif encoding == 1: encMessage_int = encMessage.decode('utf-16') else: encMessage_int = int.from_bytes(encMessage, "big") return encMessage_int class AESCipher(object): def __init__(self, key): self.bs = AES.block_size self.key = hashlib.sha256(key.encode()).digest() def encrypt(self, raw): raw = self._pad(raw) iv = Random.new().read(AES.block_size) cipher = AES.new(self.key, AES.MODE_CBC, iv) return base64.b64encode(iv + cipher.encrypt(raw.encode())) def decrypt(self, enc): enc = base64.b64decode(enc) iv = enc[:AES.block_size] cipher = AES.new(self.key, AES.MODE_CBC, iv) return AESCipher._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8') def _pad(self, s): return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs) @staticmethod def _unpad(s): return s[:-ord(s[len(s)-1:])] def invert_perm_list(p): return [p.index(l) for l in range(len(p))] def AES_decrypt(encMessage,seed,publicKey, encoding = encoding0, encryption_difficulty = encryption_difficulty0, padding = padding0): if encoding == 0: encMessage_byte = encMessage elif encoding == 1: encMessage_byte = encMessage.encode('utf-16') else: encMessage_byte = encMessage.to_bytes((encMessage.bit_length() + 7) // 8, "big") decMessage = AESCipher(str(publicKey.n)).decrypt(encMessage_byte) decMessage_len =len(decMessage) #total number of charachters in the msg permutation_list = list(range(0,decMessage_len)) random.seed(seed) random.shuffle(permutation_list) inverted_permutation_list = invert_perm_list(permutation_list) recovered_list = [decMessage[i] for i in inverted_permutation_list] recovered_msg_i_pad = ''.join(recovered_list) recovered_msg_i = int(recovered_msg_i_pad[padding:-padding]) recovered_msg = recovered_msg_i.to_bytes((recovered_msg_i.bit_length() + 7) // 8, "big").decode("utf-16") return recovered_msg def Encrypt_msg(User_message,user_password,path=''): User_passcode = (int.from_bytes(bytes(str(user_password), 'utf-8'), "little")) Num_dict_enc = seedx(path, User_passcode) encMessage_i = AES_encrypt(User_message,Num_dict_enc['seed'], Num_dict_enc['publicKey'],encoding = encoding0, padding = padding0) #print(encMessage_i) return encMessage_i def Decrypt_msg(encMessage,user_password,path=''): User_passcode = (int.from_bytes(bytes(str(user_password), 'utf-8'), "little")) Num_dict_enc = seedx(path, User_passcode) recovered_msg = AES_decrypt(encMessage,Num_dict_enc['seed'], Num_dict_enc['publicKey'], encoding = encoding0, encryption_difficulty = encryption_difficulty0, padding = padding0) #print(recovered_msg) return recovered_msg