1
0
Fork 0
mirror of https://github.com/HACKERALERT/Picocrypt.git synced 2024-12-28 10:24:19 +00:00

Update Picocrypt.py

This commit is contained in:
Evan Su 2021-03-21 17:35:29 -04:00 committed by GitHub
parent 25c716fd21
commit d3b68e8beb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,34 +1,17 @@
#!/usr/bin/env python3
"""
Dependencies: argon2-cffi, pycryptodome, reedsolo
Picocrypt v1.11 (Beta)
Dependencies: argon2-cffi, pycryptodome, reedsolo, tkinterdnd2
Copyright (c) Evan Su (https://evansu.cc)
Released under a GNU GPL v3 License
https://github.com/HACKERALERT/Picocrypt
~ In cryptography we trust ~
"""
# Test if libraries are installed
try:
from argon2.low_level import hash_secret_raw
from Crypto.Cipher import ChaCha20_Poly1305
try:
from creedsolo import ReedSolomonError
except:
from reedsolo import ReedSolomonError
except:
# Libraries missing, install them
from os import system
try:
# Debian/Ubuntu based
system("sudo apt-get install python3-tk")
except:
# Fedora
system("sudo dnf install python3-tkinter")
system("python3 -m pip install argon2-cffi --no-cache-dir")
system("python3 -m pip install pycryptodome --no-cache-dir")
system("python3 -m pip install reedsolo --no-cache-dir")
# Imports
from tkinter import filedialog,messagebox
from threading import Thread
@ -38,19 +21,15 @@ from Crypto.Cipher import ChaCha20_Poly1305
from Crypto.Hash import SHA3_512 as sha3_512
from secrets import compare_digest
from os import urandom,fsync,remove,system
from os.path import getsize,expanduser,dirname
from os.path import abspath
from TkinterDnD2 import *
from os.path import getsize,expanduser,isdir
from tkinterdnd2 import TkinterDnD,DND_FILES
import sys
import tkinter
import tkinter.ttk
import tkinter.scrolledtext
import webbrowser
import platform
try:
from creedsolo import RSCodec,ReedSolomonError
except:
from reedsolo import RSCodec,ReedSolomonError
from creedsolo import RSCodec,ReedSolomonError
# Tk/Tcl is a little barbaric, so I'm disabling
# high DPI so it doesn't scale bad and look horrible
@ -92,11 +71,6 @@ tk.title("Picocrypt")
tk.configure(background="#f5f6f7")
tk.resizable(0,0)
def onDrop(e):
print(e)
tk.drop_target_register(DND_FILES)
tk.dnd_bind("<<Drop>>",onDrop)
# Try setting window icon if included with Picocrypt
try:
favicon = tkinter.PhotoImage(file="./key.png")
@ -109,7 +83,7 @@ s = tkinter.ttk.Style()
s.configure("TCheckbutton",background="#f5f6f7")
# Event when user selects an input file
def inputSelected():
def inputSelected(draggedFile=None):
global inputFile,working,headerRsc
dummy.focus()
@ -117,13 +91,16 @@ def inputSelected():
try:
# Ask for input file
suffix = ""
tmp = filedialog.askopenfilename(
initialdir=expanduser("~")
)
if len(tmp)==0:
# Exception will be caught by except below
raise Exception("No file selected.")
inputFile = tmp
if not draggedFile:
tmp = filedialog.askopenfilename(
initialdir=expanduser("~")
)
if len(tmp)==0:
# Exception will be caught by except below
raise Exception("No file selected.")
inputFile = tmp
else:
inputFile = draggedFile
# Decide if encrypting or decrypting
if ".pcv" in inputFile.split("/")[-1]:
@ -163,6 +140,7 @@ def inputSelected():
cpasswordInput["state"] = "normal"
cpasswordInput.delete(0,"end")
cpasswordInput["state"] = "disabled"
cpasswordString.set("Confirm password (N/A):")
else:
# Update the UI
eraseBtn["state"] = "normal"
@ -174,6 +152,7 @@ def inputSelected():
adLabelString.set(adString)
cpasswordInput["state"] = "normal"
cpasswordInput.delete(0,"end")
cpasswordString.set("Confirm password:")
# Enable password box, etc.
inputString.set(inputFile.split("/")[-1]+suffix)
@ -197,6 +176,13 @@ def inputSelected():
dummy.focus()
working = False
# Allow drag and drop
def onDrop(e):
print(e.data)
inputSelected(e.data)
tk.drop_target_register(DND_FILES)
tk.dnd_bind("<<Drop>>",onDrop)
# Button to select input file
selectFileInput = tkinter.ttk.Button(
tk,
@ -304,26 +290,11 @@ def start():
pass
# Disable inputs and buttons while encrypting/decrypting
selectFileInput["state"] = "disabled"
passwordInput["state"] = "disabled"
cpasswordInput["state"] = "disabled"
adArea["state"] = "disabled"
startBtn["state"] = "disabled"
eraseBtn["state"] = "disabled"
keepBtn["state"] = "disabled"
rsBtn["state"] = "disabled"
disableAllInputs()
# Make sure passwords match
if passwordInput.get()!=cpasswordInput.get() and mode=="encrypt":
selectFileInput["state"] = "normal"
passwordInput["state"] = "normal"
cpasswordInput["state"] = "normal"
adArea["state"] = "normal"
startBtn["state"] = "normal"
eraseBtn["state"] = "normal"
rsBtn["state"] = "normal"
working = False
progress["value"] = 100
resetEncryptionUI()
statusString.set("Passwords don't match.")
return
@ -433,15 +404,7 @@ def start():
fout.close()
remove(outputFile)
# Reset UI
selectFileInput["state"] = "normal"
passwordInput["state"] = "normal"
adArea["state"] = "normal"
startBtn["state"] = "normal"
keepBtn["state"] = "normal"
working = False
progress.stop()
progress.config(mode="determinate")
progress["value"] = 100
resetDecryptionUI()
return
else:
kept = "badlyCorrupted"
@ -480,14 +443,7 @@ def start():
fout.close()
remove(outputFile)
# Reset UI
selectFileInput["state"] = "normal"
passwordInput["state"] = "normal"
adArea["state"] = "normal"
startBtn["state"] = "normal"
keepBtn["state"] = "normal"
working = False
progress["value"] = 100
del key
resetDecryptionUI()
return
# Create XChaCha20-Poly1305 object
@ -541,12 +497,7 @@ def start():
if keep.get()!=1:
remove(outputFile)
# Reset UI
selectFileInput["state"] = "normal"
passwordInput["state"] = "normal"
adArea["state"] = "normal"
startBtn["state"] = "normal"
keepBtn["state"] = "normal"
working = False
resetDecryptionUI()
del fin,fout,cipher,key
return
else:
@ -567,12 +518,7 @@ def start():
if keep.get()!=1:
remove(outputFile)
# Reset UI
selectFileInput["state"] = "normal"
passwordInput["state"] = "normal"
adArea["state"] = "normal"
startBtn["state"] = "normal"
keepBtn["state"] = "normal"
working = False
resetDecryptionUI()
del fin,fout,cipher,key
return
else:
@ -606,13 +552,7 @@ def start():
fout.close()
remove(outputFile)
# Reset UI
selectFileInput["state"] = "normal"
passwordInput["state"] = "normal"
adArea["state"] = "normal"
startBtn["state"] = "normal"
keepBtn["state"] = "normal"
working = False
progress["value"] = 100
resetDecryptionUI()
del fin,fout,cipher,key
return
else:
@ -712,27 +652,7 @@ def start():
statusString.set(kVeryCorruptedNotice)
# Reset variables and UI states
selectFileInput["state"] = "normal"
adArea["state"] = "normal"
adArea.delete("1.0",tkinter.END)
adArea["state"] = "disabled"
startBtn["state"] = "disabled"
passwordInput["state"] = "normal"
passwordInput.delete(0,"end")
passwordInput["state"] = "disabled"
cpasswordInput["state"] = "normal"
cpasswordInput.delete(0,"end")
cpasswordInput["state"] = "disabled"
progress["value"] = 0
inputString.set("Please select a file.")
keepBtn["state"] = "normal"
keep.set(0)
keepBtn["state"] = "disabled"
eraseBtn["state"] = "normal"
erase.set(0)
eraseBtn["state"] = "disabled"
rs.set(0)
rsBtn["state"] = "disabled"
resetUI()
inputFile = ""
outputFile = ""
password = ""
@ -751,36 +671,27 @@ def wrapper():
start()
except:
# Reset UI accordingly
progress.stop()
progress.config(mode="determinate")
progress["value"] = 100
selectFileInput["state"] = "normal"
passwordInput["state"] = "normal"
startBtn["state"] = "normal"
if gMode=="decrypt":
keepBtn["state"] = "normal"
resetDecryptionUI()
else:
adArea["state"] = "normal"
cpasswordInput["state"] = "normal"
rsBtn["state"] = "normal"
eraseBtn["state"] = "normal"
resetEncryptionUI()
statusString.set(unknownErrorNotice)
dummy.focus()
working = False
finally:
sys.exit(0)
# 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.
# 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.
def startWorker():
thread = Thread(target=wrapper,daemon=True)
thread.start()
# Securely wipe file
def secureWipe(fin):
statusString.set("Securely erasing original file...")
# Check platform, erase accordingly
if platform.system()=="Windows":
system(f'sdelete64.exe "{inputFile}" -p 4')
elif platform.system()=="Darwin":
@ -788,6 +699,68 @@ def secureWipe(fin):
else:
system(f'shred -uz "{inputFile}"')
# Disable all inputs while encrypting/decrypting
def disableAllInputs():
selectFileInput["state"] = "disabled"
passwordInput["state"] = "disabled"
cpasswordInput["state"] = "disabled"
adArea["state"] = "disabled"
startBtn["state"] = "disabled"
eraseBtn["state"] = "disabled"
keepBtn["state"] = "disabled"
rsBtn["state"] = "disabled"
# Reset UI to encryption state
def resetEncryptionUI():
global working
selectFileInput["state"] = "normal"
passwordInput["state"] = "normal"
cpasswordInput["state"] = "normal"
adArea["state"] = "normal"
startBtn["state"] = "normal"
eraseBtn["state"] = "normal"
rsBtn["state"] = "normal"
working = False
progress["value"] = 100
# Reset UI to decryption state
def resetDecryptionUI():
global working
selectFileInput["state"] = "normal"
passwordInput["state"] = "normal"
adArea["state"] = "normal"
startBtn["state"] = "normal"
keepBtn["state"] = "normal"
working = False
progress.stop()
progress.config(mode="determinate")
progress["value"] = 100
# Reset UI to original state (no file selected)
def resetUI():
selectFileInput["state"] = "normal"
adArea["state"] = "normal"
adArea.delete("1.0",tkinter.END)
adArea["state"] = "disabled"
startBtn["state"] = "disabled"
passwordInput["state"] = "normal"
passwordInput.delete(0,"end")
passwordInput["state"] = "disabled"
cpasswordInput["state"] = "normal"
cpasswordInput.delete(0,"end")
cpasswordInput["state"] = "disabled"
cpasswordString.set("Confirm password:")
progress["value"] = 0
inputString.set("Please select a file.")
keepBtn["state"] = "normal"
keep.set(0)
keepBtn["state"] = "disabled"
eraseBtn["state"] = "normal"
erase.set(0)
eraseBtn["state"] = "disabled"
rs.set(0)
rsBtn["state"] = "disabled"
# ad stands for "associated data"/metadata
adLabelString = tkinter.StringVar(tk)
adLabelString.set(adString)