File size: 5,637 Bytes
9b7b20b
 
 
 
 
 
 
 
 
 
 
4ac9f49
 
 
 
 
9366273
b3dc4b2
18aa8c9
7b0ab4c
9b7b20b
4ac9f49
9b7b20b
 
 
 
 
 
09317a6
9b7b20b
 
 
 
4cfb9ad
9b7b20b
4cfb9ad
 
 
9b7b20b
 
 
 
 
 
 
 
 
4cfb9ad
 
9b7b20b
 
 
22af54c
9b7b20b
 
4ac9f49
9b7b20b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4ac9f49
9b7b20b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e63086e
9b7b20b
2ec2a9e
4ac9f49
9b7b20b
 
 
 
e63086e
9b7b20b
 
4ac9f49
9b7b20b
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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