I wanted to be able to instantly encrypt/encrypt text messages over company IM, slack, email, etc. WITHOUT the use of an intermediate GUI.
I made adjustments to the original function's output methods for quick text messaging of any kind, feel free to modify or improve!
This might be overkill but I combined 2 encryption methods I found on the forums. It is a cascading cipher, and the Key is automatically set to daily changing variables, with the option to use a custom key instead of the daily rotating default key.
Use:
Encrypt:
- After launching the script, type text into something.
- Highlight the Text and press CTRL+E to encrypt it and overwrite plain text with encrypted text, then you can send your message/IM/email etc.
Decrypt:
- Highlight Encrypted Text and press CTRL+D to decrypt it and display the message in a MsgBox pop up.
- pass key automatically changes daily while encrypting or decrypting. During the hotkey press you have a prompt to use a completely custom pass key as well.
Other mods I've used beyond the basic code posted here.
- I removed the use of the pop up msg box for custom key to speed up the process. I found i rarely used the custom passkey.
- I've added in exceptions to remove linebreaks when certain apps are the active window (IMs are annoying to have a lot of line breaks in, but having line breaks in emails are easier for me to look at).
- Complex RC4 passkey: I've re-used the B64 encryption to encrypt the passkey, then strip it of random characters, flip it around and loop this several times until it reaches over 1k character undecryptable passkey (to hide how the passkey format was created in the first place to help prevent reverse engineering or likely hood someone will easily read a historical message)
Code: Select all
; ====================
; Sources:
; RC4: https://autohotkey.com/board/topic/6316-rc4-encryption-to-hex-stream
; B64: https://www.autohotkey.com/boards/viewtopic.php?p=166314#p166314
; Encrypt Functions
; =========================
b64Encode(string)
{
VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1
if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", 0, "uint*", size))
throw Exception("CryptBinaryToString failed", -1)
VarSetCapacity(buf, size << 1, 0)
if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1, "ptr", &buf, "uint*", size))
throw Exception("CryptBinaryToString failed", -1)
return StrGet(&buf)
}
b64Decode(string)
{
if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", 0, "uint*", size, "ptr", 0, "ptr", 0))
throw Exception("CryptStringToBinary failed", -1)
VarSetCapacity(buf, size, 0)
if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x1, "ptr", &buf, "uint*", size, "ptr", 0, "ptr", 0))
throw Exception("CryptStringToBinary failed", -1)
return StrGet(&buf, size, "UTF-8")
}
RC4txt2hex(Data,Pass) {
Format := A_FormatInteger
SetFormat Integer, Hex
b := 0, j := 0
VarSetCapacity(Result,StrLen(Data)*2)
Loop 256
a := A_Index - 1
,Key%a% := Asc(SubStr(Pass, Mod(a,StrLen(Pass))+1, 1))
,sBox%a% := a
Loop 256
a := A_Index - 1
,b := b + sBox%a% + Key%a% & 255
,sBox%a% := (sBox%b%+0, sBox%b% := sBox%a%) ; SWAP(a,b)
Loop Parse, Data
i := A_Index & 255
,j := sBox%i% + j & 255
,k := sBox%i% + sBox%j% & 255
,sBox%i% := (sBox%j%+0, sBox%j% := sBox%i%) ; SWAP(i,j)
,Result .= SubStr(Asc(A_LoopField)^sBox%k%, -1, 2)
StringReplace Result, Result, x, 0, All
SetFormat Integer, %Format%
Return Result
}
RC4hex2txt(Data,Pass) {
b := 0, j := 0, x := "0x"
VarSetCapacity(Result,StrLen(Data)//2)
Loop 256
a := A_Index - 1
,Key%a% := Asc(SubStr(Pass, Mod(a,StrLen(Pass))+1, 1))
,sBox%a% := a
Loop 256
a := A_Index - 1
,b := b + sBox%a% + Key%a% & 255
,sBox%a% := (sBox%b%+0, sBox%b% := sBox%a%) ; SWAP(a,b)
Loop % StrLen(Data)//2
i := A_Index & 255
,j := sBox%i% + j & 255
,k := sBox%i% + sBox%j% & 255
,sBox%i% := (sBox%j%+0, sBox%j% := sBox%i%) ; SWAP(i,j)
,Result .= Chr((x . SubStr(Data,2*A_Index-1,2)) ^ sBox%k%)
Return Result
}
; =========================
; Encrypt/Decrypt Hotkeys
; CTRL+E - Encrypt Highlighted text
; CTRL+D - Decrypt highlighted text
; =========================
; CTRL+E - Encrypt Highlighted text
^e::
RC4Pass = %A_MM%%A_DD%%A_YWeek%%A_WDay%%A_DDDD% ; Sets Pass Key for the message.
AlternateClipboard = %Clipboard% ; save current clipboard as alternate variable
Clipboard := ""
Sendinput, ^c
ClipWait, 2
if ErrorLevel
Goto, ClipFailed
MsgBox, 36, Pass Key, Do you want to use the default Pass Key to ENCRYPT your message? ; Prompt to use daily Pass Key or Custom
IfMsgBox, No
InputBox,RC4Pass, Custom Key, Enter the Pass Key to ENCTRYPT the message
RC4Enc := RC4txt2hex(clipboard,RC4Pass) ; RC4 encrypt with Pass Key
encoded := b64Encode( RC4Enc ) ; B64 encrypt
If WinActive("ahk_class AppName1") || WinActive("ahk_class AppName2") ; IF statement for commonly used IMs to output as single line for cleaner IM messages. Use WindowSpy to get App Names.
{
StringReplace, encoded, encoded, `r`n,, all
}
Clipboard = %encoded%
clipwait, 2
send, ^v
sleep, 200
Clipboard = %AlternateClipboard% ; Set clipboard to original clipboard data
encoded =
RC4Pass =
return
; CTRL+D - Decrypt highlighted text
^d::
RC4Pass = %A_MM%%A_DD%%A_YWeek%%A_WDay%%A_DDDD% ; Sets Pass Key for the message.
AlternateClipboard = %Clipboard% ; save current clipboard as alternate variable
Clipboard := ""
Sendinput, ^c
ClipWait, 2
if ErrorLevel
Goto, ClipFailed
MsgBox, 36, Pass Key, Do you want to use the default Pass Key to DECRYPT your message? ; Prompt to use daily Pass Key or Custom
IfMsgBox, No
InputBox,RC4Pass, Cipher Key, Enter the Cipher key to DECRYPT the message
decode := b64Decode( clipboard ) ; B64 decrypt
MsgBox % RC4hex2txt(decode,RC4Pass) ; RC4 decrypt with Pass Key
Clipboard = %AlternateClipboard%
sleep, 100
decode =
RC4Pass =
return
ClipFailed:
Clipboard := AlternateClipboard
Msgbox, An error occured while copying the text... try again.
return