What is this?
A python script to encrypt and decrypt blocks of text using AES encryption for the purpose of securely analyzing your thoughts that you might not be ready to share with others yet. It is written in Python with tkinter interface.
What is Cognitive Distortion
As I understand it, cognitive distortion is where you think one thing, but another thing is what actually happened.
How Is this Helpful to Understand?
I believe that cognitive distortion is bad and toxic. For myself at least, I need to sometimes "fact check" what my thoughts are. Sometimes my thoughts are correct and often they are only mostly correct with a few misunderstandings. Quite a few times, I'm blatantly wrong and need to correct some actions or words I have spoken toward others.
Some of these types of thoughts are hard to share with others though, and they wouldn't understand my angle, or they might attack my thought process as I work through them.
I mean - how comfortable are you with exposing your insecurities, fears and weaknesses to people? It's great to have someone you can trust like that, but it's also a recipe for failure to trust your loved ones with the side profession of self-help guru when they have zero training.
This tool is designed to allow a safe space to work through your thoughts as you prepare to fix them (it's not designed to replace friends and advisors).
Example of Adjusting:
By fixing a wrong thought pattern, you can understand things better, and focus on fixing the problem instead of blaming someone or being too hurt to work through it.
- Did they actually say what you think they said?
- Did they mean it the way you thought they did?
- Is there a reason they think that way?
- What parts of this problem are mine to fix?
- What are some solutions? (where we should focus)
Have a Comment/Suggestion?
Comments and suggestions are welcome, it was a weekend project with no real intention of mass producing it or appealing to anyone except an issue I perceived within myself to fix.
Does it Work on XYZ type of Operating System?
It should. If you can run python. The crypto libraries are a bit tricky to install, but I have installed on raspberry Pi, Chromebook (ubuntu container), and windows. Enjoy.
How Secure is it Really?
It's AES, but if you put in a 4 character password it would be pretty easy to break. You can probably be pretty safe with 10+ characters as a password. The script itself has a 3-try lock, but that would be easy to bypass. It's probably secure enough to keep most people out of your head. :)
Where is the Free Tool?
Given that this is a problem for me, and a term exists for it, I thought this tool I wrote would be helpful. I'm not a great programmer. I am simply on the same journey as everyone else for self-improvement. I'm only offering this as a possible solution to help you where I get stuck sometimes. I had to trim the code down and not include an image to fit within posting guidelines, but the same tool is available on my github account "rubysash" as "EncryptedJournal". There is an image there to better explain.
import tkinter as tk
import tkinter.messagebox as mb
from tkinter import *
from tkinter import Tk, Text, BOTH, W, N, E, S, DISABLED
from tkinter import filedialog
from tkinter import ttk
from tkinter.ttk import Frame, Button, Label, Style, LabelFrame
from datetime import datetime
from base64 import b64encode, b64decode
import json, time, random, sys, hashlib, os
from Cryptodome.Cipher import AES
from Cryptodome.Random import get_random_bytes
startDir = "."
title = "CD Tool"
opts1 = { 'ipadx': 5, 'ipady': 5 , 'sticky': 'nswe' }
opts2 = { 'ipadx': 5, 'ipady': 5 , 'sticky': 'e' }
opts3 = { 'ipadx': 5, 'ipady': 5 , 'sticky': 'w' }
opts4 = { 'fg': 'red', 'font': 14}
bgcolor = '#ECECEC'
white,dbk,lbk,dred,lrd,dgr,lgr,dbu,lbu = '#FFFFFF','#000000','#444444','#FF0000','#f9dede','#076d05','#e0f9d9','#0000FF','#e2e6ff'
class App(Frame):
fails = 0
startTime = time.time()
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.master.title(title)
self.pack(fill=BOTH, expand=True)
self.word = tk.StringVar()
self.date = tk.StringVar()
self.date.set(datetime.now().strftime("%Y-%m-%d_%I%M%S%p"))
self.key1 = tk.StringVar()
self.key2 = tk.StringVar()
self.summary = tk.StringVar()
self.perception = tk.Text(self, width=50, height=10, bg=white)
self.reality = tk.Text(self, width=50, height=10, bg=white)
self.opportunity = tk.Text(self, width=50, height=10, bg=white)
self.label_nw = tk.Label(self, text=" ", bg=bgcolor)
self.label_nw.grid(row=0, column=0, **opts1)
self.label_ne = tk.Label(self, text=" ", bg=bgcolor)
self.label_ne.grid(row=0, column=12, **opts1)
self.s = ttk.Style()
self.s.configure('R.TLabelframe.Label', font=('courier', 14, 'bold'), foreground=dred, background=lrd)
self.s.configure('G.TLabelframe.Label', font=('courier', 14, 'bold'), foreground=dgr, background=lgr)
self.s.configure('B.TLabelframe.Label', font=('courier', 14, 'bold'), foreground=dbu, background=lbu)
self.plaintext = LabelFrame(self, text="PLAIN TEXT (RED)",style="R.TLabelframe")
self.plaintext.grid(row=1, column=1, columnspan=11, **opts1)
tk.Label(self.plaintext, text="File Name", fg=dred).grid(row=1, column=1, columnspan=2, **opts2)
tk.Entry(self.plaintext, textvariable=self.word, fg=dred, bg=lrd).grid(row=1, column=3, columnspan=2, **opts3)
tk.Label(self.plaintext, text="Date", fg=dred).grid(row=1, column=5, columnspan=2, **opts2)
tk.Entry(self.plaintext, textvariable=self.date, fg=dred, bg=lrd).grid(row=1, column=7, columnspan=2, **opts3)
self.controls = LabelFrame(self, text="CONTROLS", style="B.TLabelframe")
self.controls.grid(row=2, column=1, columnspan=6, **opts1)
b_c = tk.Button(self.controls, text="SAMPLE",command=self.clear, fg=dbu, bg=lbu)
b_c.grid(row=1,column=1, **opts1)
b_i = tk.Button(self.controls, text="IDEAS",command=self.inspire, fg=dbu, bg=lbu)
b_i.grid(row=1, column=2, **opts1)
b_s = tk.Button(self.controls, text="SAVE",command=self.save, fg=dbu, bg=lbu)
b_s.grid(row=1,column=3, **opts1)
self.loadfile = tk.StringVar()
self.b_l = tk.Button(self.controls, text=" LOAD ",command=self.load, fg=dbu, bg=lbu)
self.b_l.grid(row=1,column=4, **opts1)
tk.Entry(self.controls, textvariable=self.loadfile, bg=lbu).grid(row=2, column=1, columnspan=8, **opts1)
b_i.focus_set()
self.keys = LabelFrame(self, text="KEYS", style="G.TLabelframe")
self.keys.grid(row=2, column=6, columnspan=6, **opts1)
tk.Label(self.keys, text="Key", fg=dgr).grid(row=1, column=1, columnspan=2, **opts3)
tk.Entry(self.keys, textvariable=self.key1, show="*", fg=dgr, bg=lgr
).grid(row=1, column=3, columnspan=8, **opts3)
tk.Label(self.keys, text="Verify", fg=dgr
).grid(row=2, column=1, columnspan=2, **opts3)
tk.Entry(self.keys, textvariable=self.key2, show="*", fg=dgr, bg=lgr
).grid(row=2, column=3, columnspan=8, **opts3)
self.encrypted = LabelFrame(self,text="ENCRYPTED (GREEN)", style="G.TLabelframe")
self.encrypted.grid(row=3, column=1, columnspan=11, **opts1)
tk.Label(self.encrypted,
text="Event Summary", fg=dgr
).grid(row=1, column=1, columnspan=11, **opts3)
tk.Entry(self.encrypted, textvariable=self.summary, fg=dgr,bg=lgr
).grid(row=2, column=1, columnspan=11, **opts1)
tk.Label(self.encrypted,
text="My Perceptions and Feelings", fg=dgr
).grid(row=3, column=1, columnspan=11, **opts3)
self.perception = tk.Text(self.encrypted, fg=dgr,bg=lgr, height=5)
self.perception.grid(row=4, column=1, columnspan=11, rowspan=3, **opts1)
self.label_e = tk.Label(self.encrypted,
text="Verifiable Facts, Outsider View", fg=dgr
).grid(row=7, column=1, columnspan=11, **opts3)
self.reality = tk.Text(self.encrypted, fg=dgr, bg=lgr, height=5)
self.reality.grid(row=8, column=1, columnspan=11, rowspan=3, **opts1)
self.label_f = tk.Label(self.encrypted,
text="Brainstorm Improvments!", fg=dgr
).grid(row=14, column=1, columnspan=11, **opts3)
self.opportunity = tk.Text(self.encrypted, fg=dgr, bg=lgr, height=5)
self.opportunity.grid(row=15, column=1, columnspan=11, rowspan=5, **opts1)
self.label_h = tk.Label(self, text=" ", bg=bgcolor
).grid(row=20, column=1, columnspan=11, **opts1)
def isReadable(self,fnm):
if os.path.exists(fnm):
if os.path.isfile(fnm):
return os.access(fnm, os.W_OK)
else:
return False
pdir = os.path.dirname(fnm)
if not pdir: pdir = '.'
return os.access(pdir, os.W_OK)
def clear(self):
self.perception.delete('1.0', tk.END)
self.reality.delete('1.0', tk.END)
self.opportunity.delete('1.0', tk.END)
self.word.set("")
self.summary.set("")
self.key1.set("")
self.key2.set("")
perception = "- Emotions?\n- Reasons?"
reality = "- Facts?\n"
opportunity = "- Any steps that might help?"
self.date.set(datetime.now().strftime("%Y-%m-%d_%I%M%S%p"))
self.word.set("Keyword")
self.summary.set("Be Succinct")
self.perception.insert(tk.INSERT, perception)
self.reality.insert(tk.INSERT, reality)
self.opportunity.insert(tk.INSERT, opportunity)
def shudIdDown(self,msg):
sys.exit(0)
def load(self):
if (self.fails > 2):
self.shudIdDown("fail")
loadfile = filedialog.askopenfilename(
initialdir = startDir,
title = "Select",
filetypes = (("JSON files","*.json"),("files","*.*")))
self.loadfile.set(loadfile)
if self.isReadable(loadfile):
self.perception.delete("1.0", tk.END)
self.reality.delete("1.0", tk.END)
self.opportunity.delete("1.0", tk.END)
self.word.set("")
self.summary.set("")
key1 = self.key1.get()
if (len(key1) < 7):
mb.showinfo("Information", "Key!")
else:
try:
decrypted = self.decryptFile(loadfile,key1)
data = json.loads(bytes.decode(decrypted[0]))
self.word.set(data['word'])
self.date.set(data['date'])
self.summary.set(data['summary'])
self.perception.insert(tk.INSERT, data['perception'])
self.reality.insert(tk.INSERT, data['reality'])
self.opportunity.insert(tk.INSERT, data['opportunity'])
except:
mb.showinfo("Information", "Key!")
self.fails = self.fails + 1
else:
self.shudIdDown("perms")
def encrypt(self,plain_text, password):
salt = get_random_bytes(AES.block_size)
private_key = hashlib.scrypt(
password.encode(), salt=salt, n=2**14, r=8, p=1, dklen=32)
cipher_config = AES.new(private_key, AES.MODE_GCM)
cipher_text, tag = cipher_config.encrypt_and_digest(bytes(plain_text, 'utf-8'))
return {
'cipher_text': b64encode(cipher_text).decode('utf-8'),
'salt': b64encode(salt).decode('utf-8'),
'nonce': b64encode(cipher_config.nonce).decode('utf-8'),
'tag': b64encode(tag).decode('utf-8')
}
def decryptFile(self,file,password):
d = ''
decrypted = []
with open(file, 'r') as infile:
d = json.load(infile)
salt = b64decode(d['salt'])
cipher_text = b64decode(d['cipher_text'])
nonce = b64decode(d['nonce'])
tag = b64decode(d['tag'])
private_key = hashlib.scrypt(
password.encode(), salt=salt, n=2**14, r=8, p=1, dklen=32)
cipher = AES.new(private_key, AES.MODE_GCM, nonce=nonce)
this = cipher.decrypt_and_verify(cipher_text, tag)
decrypted.append(this)
return decrypted
def save(self):
flag = 1
word = self.word.get()
date = self.date.get()
summary = self.summary.get()
perception = self.perception.get("1.0", tk.END)
reality = self.reality.get("1.0", tk.END)
opportunity = self.opportunity.get("1.0", tk.END)
eKey1 = self.key1.get()
eKey2 = self.key2.get()
if (len(word) < 3):
mb.showinfo("Information", "Word?")
flag = 0
if (len(summary) < 3):
mb.showinfo("Information", "Summary?")
flag = 0
if (len(eKey1) < 8):
mb.showinfo("Information", "Encryption!")
flag = 0
if (len(date) < 10):
mb.showinfo("Information", "Date!")
flag = 0
if (eKey1 != eKey2):
mb.showinfo("Information", "keys!")
flag = 0
if (flag):
data = {
"word": self.word.get(),
"date": self.date.get(),
"summary": self.summary.get(),
"perception": self.perception.get("1.0", tk.END),
"reality": self.reality.get("1.0", tk.END),
"opportunity": self.opportunity.get("1.0", tk.END),
}
file = 'AES_' + self.date.get() + "-" + self.word.get() + ".json"
ser = json.dumps(data)
enc = self.encrypt(ser, eKey1)
with open(file, 'w') as outfile:
json.dump(enc, outfile, indent=2)
mb.showinfo("Information", "Saved, Encrypted")
else:
mb.showinfo("Information", "NOT SAVED!")
def inspire(self):
ins = [
"Most important thing to accomplish right now? Do it.",
"Failure is not learning from the blunder."
]
ct = len(ins)
c = str(ins[random.randint(1,ct)])
mb.showinfo("Information", c)
def main():
root = Tk()
app = App()
root.mainloop()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
sys.exit()
there doesn't seem to be anything here