mirror of
https://github.com/HACKERALERT/Picocrypt.git
synced 2025-01-01 12:22:25 +00:00
Update Picocrypt.py
This commit is contained in:
parent
d3b68e8beb
commit
376617e30d
1 changed files with 88 additions and 12 deletions
|
@ -22,7 +22,12 @@ from Crypto.Hash import SHA3_512 as sha3_512
|
||||||
from secrets import compare_digest
|
from secrets import compare_digest
|
||||||
from os import urandom,fsync,remove,system
|
from os import urandom,fsync,remove,system
|
||||||
from os.path import getsize,expanduser,isdir
|
from os.path import getsize,expanduser,isdir
|
||||||
|
from os.path import dirname,abspath
|
||||||
|
from os.path import join as pathJoin
|
||||||
|
from os.path import split as pathSplit
|
||||||
from tkinterdnd2 import TkinterDnD,DND_FILES
|
from tkinterdnd2 import TkinterDnD,DND_FILES
|
||||||
|
from zipfile import ZipFile
|
||||||
|
from pathlib import Path
|
||||||
import sys
|
import sys
|
||||||
import tkinter
|
import tkinter
|
||||||
import tkinter.ttk
|
import tkinter.ttk
|
||||||
|
@ -42,13 +47,17 @@ except:
|
||||||
# Global variables and notices
|
# Global variables and notices
|
||||||
inputFile = ""
|
inputFile = ""
|
||||||
outputFile = ""
|
outputFile = ""
|
||||||
|
outputPath = ""
|
||||||
password = ""
|
password = ""
|
||||||
ad = ""
|
ad = ""
|
||||||
kept = False
|
kept = False
|
||||||
working = False
|
working = False
|
||||||
gMode = None
|
gMode = None
|
||||||
headerRsc = None
|
headerRsc = None
|
||||||
|
draggedFiles = False
|
||||||
|
dragFolderPath = False
|
||||||
adString = "File metadata (used to store some text along with the file):"
|
adString = "File metadata (used to store some text along with the file):"
|
||||||
|
compressingNotice = "Compressing files together..."
|
||||||
passwordNotice = "Error. The provided password is incorrect."
|
passwordNotice = "Error. The provided password is incorrect."
|
||||||
corruptedNotice = "Error. The input file is corrupted."
|
corruptedNotice = "Error. The input file is corrupted."
|
||||||
veryCorruptedNotice = "Error. The input file and header keys are badly corrupted."
|
veryCorruptedNotice = "Error. The input file and header keys are badly corrupted."
|
||||||
|
@ -84,11 +93,16 @@ s.configure("TCheckbutton",background="#f5f6f7")
|
||||||
|
|
||||||
# Event when user selects an input file
|
# Event when user selects an input file
|
||||||
def inputSelected(draggedFile=None):
|
def inputSelected(draggedFile=None):
|
||||||
global inputFile,working,headerRsc
|
global inputFile,working,headerRsc,draggedFiles
|
||||||
|
global dragFolderPath
|
||||||
dummy.focus()
|
dummy.focus()
|
||||||
|
status.config(cursor="")
|
||||||
|
status.bind("<Button-1>",lambda e:None)
|
||||||
|
|
||||||
# Try to handle when select file is cancelled
|
# Try to handle when select file is cancelled
|
||||||
try:
|
try:
|
||||||
|
draggedFiles = None
|
||||||
|
dragFolderPath = None
|
||||||
# Ask for input file
|
# Ask for input file
|
||||||
suffix = ""
|
suffix = ""
|
||||||
if not draggedFile:
|
if not draggedFile:
|
||||||
|
@ -100,7 +114,20 @@ def inputSelected(draggedFile=None):
|
||||||
raise Exception("No file selected.")
|
raise Exception("No file selected.")
|
||||||
inputFile = tmp
|
inputFile = tmp
|
||||||
else:
|
else:
|
||||||
inputFile = draggedFile
|
# Check if multiple files
|
||||||
|
if "} {" in draggedFile:
|
||||||
|
draggedFiles = draggedFile[1:-1]
|
||||||
|
draggedFiles = draggedFiles.split("} {")
|
||||||
|
elif " " in draggedFile and "{" not in draggedFile:
|
||||||
|
draggedFiles = draggedFile.split()
|
||||||
|
else:
|
||||||
|
if isdir(draggedFile):
|
||||||
|
draggedFiles = Path(draggedFile).rglob("*")
|
||||||
|
draggedFiles = [abspath(i) for i in draggedFiles]
|
||||||
|
dragFolderPath = draggedFile
|
||||||
|
else:
|
||||||
|
draggedFile = draggedFile.replace("{","")
|
||||||
|
inputFile = draggedFile.replace("}","")
|
||||||
|
|
||||||
# Decide if encrypting or decrypting
|
# Decide if encrypting or decrypting
|
||||||
if ".pcv" in inputFile.split("/")[-1]:
|
if ".pcv" in inputFile.split("/")[-1]:
|
||||||
|
@ -154,8 +181,14 @@ def inputSelected(draggedFile=None):
|
||||||
cpasswordInput.delete(0,"end")
|
cpasswordInput.delete(0,"end")
|
||||||
cpasswordString.set("Confirm password:")
|
cpasswordString.set("Confirm password:")
|
||||||
|
|
||||||
|
# Show selected file(s)
|
||||||
|
if draggedFiles:
|
||||||
|
inputString.set(f"{len(draggedFiles)} files selected"+
|
||||||
|
" (will encrypt).")
|
||||||
|
else:
|
||||||
|
inputString.set(inputFile.split("/")[-1]+suffix)
|
||||||
|
|
||||||
# Enable password box, etc.
|
# Enable password box, etc.
|
||||||
inputString.set(inputFile.split("/")[-1]+suffix)
|
|
||||||
passwordInput["state"] = "normal"
|
passwordInput["state"] = "normal"
|
||||||
passwordInput.delete(0,"end")
|
passwordInput.delete(0,"end")
|
||||||
startBtn["state"] = "normal"
|
startBtn["state"] = "normal"
|
||||||
|
@ -169,7 +202,8 @@ def inputSelected(draggedFile=None):
|
||||||
|
|
||||||
# No file selected, do nothing
|
# No file selected, do nothing
|
||||||
except:
|
except:
|
||||||
pass
|
inputString.set("Please select a file.")
|
||||||
|
resetUI()
|
||||||
|
|
||||||
# Focus the dummy button to remove ugly borders
|
# Focus the dummy button to remove ugly borders
|
||||||
finally:
|
finally:
|
||||||
|
@ -178,7 +212,6 @@ def inputSelected(draggedFile=None):
|
||||||
|
|
||||||
# Allow drag and drop
|
# Allow drag and drop
|
||||||
def onDrop(e):
|
def onDrop(e):
|
||||||
print(e.data)
|
|
||||||
inputSelected(e.data)
|
inputSelected(e.data)
|
||||||
tk.drop_target_register(DND_FILES)
|
tk.drop_target_register(DND_FILES)
|
||||||
tk.dnd_bind("<<Drop>>",onDrop)
|
tk.dnd_bind("<<Drop>>",onDrop)
|
||||||
|
@ -256,7 +289,9 @@ cpasswordInput["state"] = "disabled"
|
||||||
|
|
||||||
# Start the encryption/decryption process
|
# Start the encryption/decryption process
|
||||||
def start():
|
def start():
|
||||||
global inputFile,outputFile,password,ad,kept,working,gMode,headerRsc
|
global inputFile,outputFile,password,ad,kept
|
||||||
|
global working,gMode,headerRsc,draggedFiles
|
||||||
|
global dragFolderPath
|
||||||
dummy.focus()
|
dummy.focus()
|
||||||
reedsolo = False
|
reedsolo = False
|
||||||
chunkSize = 2**20
|
chunkSize = 2**20
|
||||||
|
@ -308,6 +343,28 @@ def start():
|
||||||
# 13 bytes per 128 bytes, ~10% larger output file
|
# 13 bytes per 128 bytes, ~10% larger output file
|
||||||
rsc = RSCodec(13)
|
rsc = RSCodec(13)
|
||||||
|
|
||||||
|
# Compress files together if user dragged multiple files
|
||||||
|
if draggedFiles:
|
||||||
|
statusString.set(compressingNotice)
|
||||||
|
tmp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
if dragFolderPath:
|
||||||
|
zfName = Path(dragFolderPath).parent.absolute()
|
||||||
|
zfName = pathJoin(zfName,tmp+".zip")
|
||||||
|
else:
|
||||||
|
zfName = Path(draggedFiles[0]).parent.absolute()
|
||||||
|
zfName = pathJoin(zfName,tmp+".zip")
|
||||||
|
zf = ZipFile(zfName,"w")
|
||||||
|
for i in draggedFiles:
|
||||||
|
if dragFolderPath:
|
||||||
|
nameOffset = len(dragFolderPath)
|
||||||
|
zf.write(i,i[nameOffset:])
|
||||||
|
else:
|
||||||
|
zf.write(i,pathSplit(i)[1])
|
||||||
|
zf.close()
|
||||||
|
inputFile = zfName
|
||||||
|
outputFile = zfName+".pcv"
|
||||||
|
outputPath = dirname(outputFile)
|
||||||
|
|
||||||
# Set and get some variables
|
# Set and get some variables
|
||||||
working = True
|
working = True
|
||||||
headerBroken = False
|
headerBroken = False
|
||||||
|
@ -623,14 +680,25 @@ def start():
|
||||||
done += 1104905 if (reedsolo and mode=="decrypt") else chunkSize
|
done += 1104905 if (reedsolo and mode=="decrypt") else chunkSize
|
||||||
fout.write(data)
|
fout.write(data)
|
||||||
|
|
||||||
|
# Flush outputs, close files
|
||||||
if not kept:
|
if not kept:
|
||||||
fout.flush()
|
fout.flush()
|
||||||
fsync(fout.fileno())
|
fsync(fout.fileno())
|
||||||
fout.close()
|
fout.close()
|
||||||
fin.close()
|
fin.close()
|
||||||
|
|
||||||
|
# Securely wipe files as necessary
|
||||||
if wipe:
|
if wipe:
|
||||||
|
progress.config(mode="indeterminate")
|
||||||
|
progress.start(15)
|
||||||
|
if draggedFiles:
|
||||||
|
for i in draggedFiles:
|
||||||
|
print("==============="+i)
|
||||||
|
secureWipe(i)
|
||||||
secureWipe(inputFile)
|
secureWipe(inputFile)
|
||||||
|
else:
|
||||||
|
if draggedFiles:
|
||||||
|
remove(inputFile)
|
||||||
|
|
||||||
# Show appropriate notice if file corrupted or modified
|
# Show appropriate notice if file corrupted or modified
|
||||||
if not kept:
|
if not kept:
|
||||||
|
@ -651,6 +719,9 @@ def start():
|
||||||
else:
|
else:
|
||||||
statusString.set(kVeryCorruptedNotice)
|
statusString.set(kVeryCorruptedNotice)
|
||||||
|
|
||||||
|
status.config(cursor="hand2")
|
||||||
|
status.bind("<Button-1>",lambda e:print(outputPath))
|
||||||
|
|
||||||
# Reset variables and UI states
|
# Reset variables and UI states
|
||||||
resetUI()
|
resetUI()
|
||||||
inputFile = ""
|
inputFile = ""
|
||||||
|
@ -659,6 +730,8 @@ def start():
|
||||||
ad = ""
|
ad = ""
|
||||||
kept = False
|
kept = False
|
||||||
working = False
|
working = False
|
||||||
|
draggedFiles = False
|
||||||
|
dragFolderPath = False
|
||||||
|
|
||||||
# Wipe keys for safety
|
# Wipe keys for safety
|
||||||
del fin,fout,cipher,key
|
del fin,fout,cipher,key
|
||||||
|
@ -667,9 +740,9 @@ def start():
|
||||||
def wrapper():
|
def wrapper():
|
||||||
global working,gMode
|
global working,gMode
|
||||||
# Try start() and handle errors
|
# Try start() and handle errors
|
||||||
try:
|
#try:
|
||||||
start()
|
start()
|
||||||
except:
|
'''except:
|
||||||
# Reset UI accordingly
|
# Reset UI accordingly
|
||||||
|
|
||||||
if gMode=="decrypt":
|
if gMode=="decrypt":
|
||||||
|
@ -680,7 +753,7 @@ def wrapper():
|
||||||
statusString.set(unknownErrorNotice)
|
statusString.set(unknownErrorNotice)
|
||||||
dummy.focus()
|
dummy.focus()
|
||||||
finally:
|
finally:
|
||||||
sys.exit(0)
|
sys.exit(0)'''
|
||||||
|
|
||||||
# Encryption/decrypt is done is a separate thread so the UI
|
# Encryption/decrypt is done is a separate thread so the UI
|
||||||
# isn't blocked. This is a wrapper to spawn a thread and start it.
|
# isn't blocked. This is a wrapper to spawn a thread and start it.
|
||||||
|
@ -693,11 +766,11 @@ def secureWipe(fin):
|
||||||
statusString.set("Securely erasing original file...")
|
statusString.set("Securely erasing original file...")
|
||||||
# Check platform, erase accordingly
|
# Check platform, erase accordingly
|
||||||
if platform.system()=="Windows":
|
if platform.system()=="Windows":
|
||||||
system(f'sdelete64.exe "{inputFile}" -p 4')
|
system(f'sdelete64.exe "{fin}" -p 4')
|
||||||
elif platform.system()=="Darwin":
|
elif platform.system()=="Darwin":
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
system(f'shred -uz "{inputFile}"')
|
system(f'shred -uz "{fin}" -n 4')
|
||||||
|
|
||||||
# Disable all inputs while encrypting/decrypting
|
# Disable all inputs while encrypting/decrypting
|
||||||
def disableAllInputs():
|
def disableAllInputs():
|
||||||
|
@ -760,6 +833,9 @@ def resetUI():
|
||||||
eraseBtn["state"] = "disabled"
|
eraseBtn["state"] = "disabled"
|
||||||
rs.set(0)
|
rs.set(0)
|
||||||
rsBtn["state"] = "disabled"
|
rsBtn["state"] = "disabled"
|
||||||
|
progress.stop()
|
||||||
|
progress.config(mode="determinate")
|
||||||
|
progress["value"] = 0
|
||||||
|
|
||||||
# ad stands for "associated data"/metadata
|
# ad stands for "associated data"/metadata
|
||||||
adLabelString = tkinter.StringVar(tk)
|
adLabelString = tkinter.StringVar(tk)
|
||||||
|
|
Loading…
Reference in a new issue