228 lines
5.7 KiB
Python
228 lines
5.7 KiB
Python
import base64
|
|
import hashlib
|
|
from Crypto import Random
|
|
from Crypto.Cipher import AES
|
|
import string
|
|
import time
|
|
|
|
BS = 16
|
|
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS).encode()
|
|
unpad = lambda s: s[:-ord(s[len(s)-1:])]
|
|
|
|
def iv():
|
|
"""
|
|
The initialization vector to use for encryption or decryption.
|
|
It is ignored for MODE_ECB and MODE_CTR.
|
|
"""
|
|
return chr(0) * 16
|
|
|
|
class AESCipher(object):
|
|
"""
|
|
https://github.com/dlitz/pycrypto
|
|
"""
|
|
|
|
def __init__(self, key):
|
|
self.key = key
|
|
#self.key = hashlib.sha256(key.encode()).digest()
|
|
|
|
def encrypt(self, message):
|
|
"""
|
|
It is assumed that you use Python 3.0+
|
|
, so plaintext's type must be str type(== unicode).
|
|
"""
|
|
message = message.encode()
|
|
raw = pad(message)
|
|
cipher = AES.new(self.key, AES.MODE_CBC, iv())
|
|
enc = cipher.encrypt(raw)
|
|
return base64.b64encode(enc).decode('utf-8')
|
|
|
|
def decrypt(self, enc):
|
|
enc = base64.b64decode(enc)
|
|
cipher = AES.new(self.key, AES.MODE_CBC, iv())
|
|
dec = cipher.decrypt(enc)
|
|
return unpad(dec).decode('utf-8')
|
|
|
|
class question:
|
|
def __init__(self, qtype, qproblem, qoption1, qoption2, qoption3, qoption4):
|
|
qtype = self.qtype
|
|
qproblem = self.qproblem
|
|
qoption1 = self.qoption1
|
|
qoption2 = self.qoption2
|
|
qoption3 = self.qoption3
|
|
qoption4 = self.qoption4
|
|
|
|
|
|
class libexam:
|
|
mode = 0
|
|
mode_set = 0
|
|
|
|
username = ""
|
|
questions = []
|
|
|
|
def setmode(modein):
|
|
mode=modein
|
|
modeset=1
|
|
print(f"Mode set to: {mode}\n") #1: client 2: admin
|
|
return 0
|
|
|
|
def status():
|
|
return f"""Mode: {mode}
|
|
Username: {username}\n"""
|
|
|
|
|
|
def setuser(user):
|
|
username=user
|
|
print(f"Username set to: {user}\n")
|
|
return 0
|
|
|
|
def readquestions():
|
|
sha256=hashlib.sha256()
|
|
|
|
questiondocs = open("question.txt", "r")
|
|
n = questiondocs.readline()
|
|
sha256.update(n)
|
|
|
|
print(f"n={n}\n")
|
|
|
|
counter=n
|
|
while(True):#hash check
|
|
temp = questiondocs.readline()
|
|
if(temp=="chk"):
|
|
sha256.update(temp)
|
|
|
|
rhash = sha256.digest()
|
|
ehash = questiondocs.readline()
|
|
|
|
if(rhash==ehash):
|
|
print(f"Hashes match: {rhash}\n")
|
|
break
|
|
else:
|
|
print(f"Hashes does not match !\nExpected: {ehash}\nGot: {rhash}\n")
|
|
return 1
|
|
sha256.update(temp)
|
|
|
|
questiondocs.close()
|
|
questiondocs = open("question.txt", "r")
|
|
temp = questiondocs.readline()
|
|
|
|
|
|
|
|
while(True):
|
|
temp = questiondocs.readline()
|
|
if(temp=="chk"):
|
|
break
|
|
qtype = temp
|
|
|
|
temp = questiondocs.readline()
|
|
temp = temp.split("|")
|
|
|
|
questions.append(question(qtype,temp[0],temp[1],temp[2],temp[3],temp[4]))
|
|
|
|
|
|
|
|
def writeanswer(qn,ans)
|
|
if(username=""){
|
|
print(f"Username not set!\n")
|
|
return 1
|
|
}
|
|
|
|
|
|
|
|
md5 = hashlib.md5()
|
|
md5.update(username)
|
|
filename = md5.digest()
|
|
print(f"MD5 hash of {user}: {filename}")
|
|
|
|
sha256 = hashlib.sha256()
|
|
|
|
|
|
datadocs = open(f"{filename}.txt", "r")
|
|
n = datadocs.readline()
|
|
sha256.update(n)
|
|
|
|
while(True):#hash check
|
|
temp = data.readline()
|
|
if(temp=="chk"):
|
|
sha256.update(temp)
|
|
|
|
rhash = sha256.digest()
|
|
ehash = data.readline()
|
|
|
|
if(rhash==ehash):
|
|
print(f"Hashes match: {rhash}\n")
|
|
break
|
|
else:
|
|
print(f"Hashes does not match !\nExpected: {ehash}\nGot: {rhash}\n")
|
|
return 1
|
|
sha256.update(temp)
|
|
|
|
|
|
datadocs.close()
|
|
datadocs = open(f"{filename}.txt", "r+")
|
|
|
|
timestamp = hex(int(time.time()))#part c of a line according to docs
|
|
while(len(timestamp) != 16):
|
|
timestamp = "0" + timestamp
|
|
|
|
cd = timestamp + ans
|
|
|
|
bhash = hashlib.sha256()
|
|
bhash.update(cd)
|
|
b = bhash.digest()
|
|
|
|
print(f"Timestamp: {timestamp}\nAnswer: {ans}\nPart B Hash: {b}")
|
|
|
|
userhash = hashlib.sha256()
|
|
userhash.update(username)
|
|
key = userhash.digest()#generated key for encryption
|
|
|
|
print(f"Key generated: {key}\n")
|
|
|
|
bcd = AESCipher(key).encrypt(b + cd) #encrypt
|
|
|
|
print(f"Parts B C D Encrypted: {bcd}\n")
|
|
|
|
ahash = hashlib.sha256()
|
|
ahash.update(bcd)
|
|
a = ahash.digest()
|
|
|
|
print(f"Parts A Hash: {a}\n")
|
|
print(f"Data to write: {a + bcd}\n")
|
|
|
|
# read a list of lines into data
|
|
data = datadocs.readlines()
|
|
|
|
# now change the answer line, note that you have to add a newline
|
|
data[qn] = a + bcd
|
|
|
|
# and write everything back
|
|
datadocs.writelines(data)
|
|
datadocs.close()
|
|
|
|
|
|
datadocs = open(f"{filename}.txt", "r+")
|
|
n = datadocs.readline()
|
|
sha256.update(n)
|
|
|
|
while(True):#calculate hash
|
|
temp = data.readline()
|
|
if(temp=="chk"):
|
|
sha256.update(temp)
|
|
targethash = data.readline()
|
|
break
|
|
sha256.update(temp)
|
|
|
|
print(f"New hash generated: {targethash}\n")
|
|
|
|
|
|
# read a list of lines into data
|
|
data = datadocs.readlines()
|
|
|
|
# now change the answer line, note that you have to add a newline
|
|
data[1+n] = targethash
|
|
|
|
# and write everything back
|
|
datadocs.writelines(data)
|
|
datadocs.close()
|
|
|
|
return 0
|