Skip to content

Instantly share code, notes, and snippets.

@asmoore82
Last active July 27, 2022 16:42
Show Gist options
  • Save asmoore82/5113c990daedf3720d2dd7bf23bd4bde to your computer and use it in GitHub Desktop.
Save asmoore82/5113c990daedf3720d2dd7bf23bd4bde to your computer and use it in GitHub Desktop.
AutoHotKey script to use any clipboard manager to store encrypted passwords.
; SuperPaste - Encrypt/Decrypt/Autotype the clipboard contents
; - Most useful with a separate clipboard manager, hopefully should work with any
; - RC4 with salt is used for encryption, NOTE THAT THIS IS *NOT* STRONG ENCRYPTION! Its purpose is just
; - to prevent the plaintext password from sitting on the clipboard
; - to prevent the plaintext password from being stored in the clipboard manager files
; - to prevent anyone from easily viewing the plaintext either over the shoulder or on screenshare
; - A simple padding is added to the beginning and end of your plaintext to protect against accidentally decrypting
; and using an incomplete item, but this does not protect against items where the middle has been altered
; - To prevent anyone from walking up to your workstation and using these shortcuts to reveal your plaintext
; passwords, either close this script or set a blank or wrong encryption password before you walk away
; ----------------------------------------------------------------
; Global Hotkey Defaults
;
; - ctrl+shift+p for prompt for encryption password
; - this runs automatically at every script start
; - this immediately makes all encrypted clipboard items unusuable until the correct password is re-entered
; - this password is never saved to disk
;
; - ctrl+shift+e for encrypt new item
; - this first prompts for a nametag so that you can easily recognize it after encryption
; - then prompts for the text to be encrypted
; - the encrypted result is insterted on the clipboard
; - you can change the name tag easily at any time, anything before the RC4:... is ignored
;
; - ctrl+shift+d for decrypt and type item from clipboard
; - this works even in applications that attempt to block the standard paste function for password fields
;
; - ctrl+alt+d for decrypt, click, and type item clipboard
; - the extra click is useful for appliations that normally intercept hotkeys such as VMWare Horizon Client,
; you need to have them open but not focused and hover the mouse over them before using the hotkeys,
; the initial click will focus them and then the decrypted contents will be sent
;
; - ctrl+shift+v for virtual paste - type item from clipboard
; - this is for typing any other plaintext from the clipboard into apps that won't or can't accept
; the normal paste function, such as VM's under VMWare HTML5 viewer.
;
; - ctrl+alt+p for paste slowly - send delayed events from clipboard
; - this is an alternate method for typing plaintext from the clipboard, works with X11 Linux VM's under VMWare HTML5 viewer
; ----------------------------------------------------------------
SuperPaste_AskPass() {
Global SuperPaste_RC4Pass := ""
InputBox, SuperPaste_RC4Pass, SuperPaste, Encryption password, HIDE
Return
}
SuperPaste_alphaSet := "0123456789"
. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
. "abcdefghijklmnopqrstuvwxyz"
SuperPaste_alphaMax := StrLen(SuperPaste_alphaSet)
SuperPaste_PassTheSalt(Length := 8) {
Global SuperPaste_alphaSet, Global SuperPaste_alphaMax
Loop, %Length%
{
Random, rnd, 1, SuperPaste_alphaMax
x .= SubStr(SuperPaste_alphaSet, rnd, 1)
}
Return x
}
SuperPaste_Encrypt() {
Global SuperPaste_RC4Pass
InputBox, tag, SuperPaste, Nametag?
if (ErrorLevel > 0)
Return
InputBox, passwd, SuperPaste, Password, HIDE
if (ErrorLevel > 0)
Return
salt := SuperPaste_PassTheSalt()
txt := "RC4:" . passwd . ":RC4"
hex := RC4txt2hex(txt, salt . SuperPaste_RC4Pass)
Clipboard := tag . " RC4S:" . b64Encode(hex) . ":" . salt
Return
}
SuperPaste_Decrypt_Error()
{
MsgBox, 0x30, SuperPaste, Decryption failed.
Exit
}
SuperPaste_Decrypt(P_Click := False)
{
Global SuperPaste_RC4Pass
index := InStr(Clipboard, "RC4S:")
if (index > 0) {
enc := SubStr(Clipboard, index+5)
ar := StrSplit(enc, ":")
enc := ar[1]
salt := ar[2]
} else {
index := InStr(Clipboard, "RC4:")
if (index > 0) {
enc := SubStr(Clipboard, index+4)
ar := StrSplit(enc, ":")
salt := ar[1]
enc := ar[2]
} else {
SuperPaste_Decrypt_Error()
}
}
hex := b64Decode(enc)
txt := RC4hex2txt(hex, salt . SuperPaste_RC4Pass)
txt_l := StrLen(txt)
if ((SubStr(txt, 1, 4) != "RC4:") || (SubStr(txt, txt_l - 3) != ":RC4"))
SuperPaste_Decrypt_Error()
txt := SubStr(txt, 5, txt_l - 8)
if P_Click {
Click
Sleep, 100
}
SendInput {Raw}%txt%
Return
}
; ----------------------------------------------------------------
; External Source:
; B64: https://github.com/jNizM/AHK_Scripts/blob/master/src/encoding_decoding/base64.ahk
; ----------------------------------------------------------------
b64Encode(string)
{
VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1
if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x40000001, "ptr", 0, "uint*", size))
throw Exception("CryptBinaryToString failed", -1)
VarSetCapacity(buf, size << 1, 0)
if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x40000001, "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")
}
; ----------------------------------------------------------------
; External Source:
; RC4: https://autohotkey.com/board/topic/6316-rc4-encryption-to-hex-stream
; ----------------------------------------------------------------
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
}
; ----------------------------------------------------------------
; Main()
; ----------------------------------------------------------------
SuperPaste_AskPass()
; ----------------------------------------------------------------
; Global Hotkeys
; ----------------------------------------------------------------
; ctrl+shift+p for password prompt
^+p::
SuperPaste_AskPass()
Return
; ctrl+shift+e for encrypt new item
^+e::
SuperPaste_Encrypt()
Return
; ctrl+shift+d for decrypt and type item from clipboard
^+d::
SuperPaste_Decrypt()
Return
; ctrl+alt+d for decrypt, click, and type item clipboard
^!d::
SuperPaste_Decrypt(True)
Return
; ctrl+shift+v for virtual paste - type item from clipboard
^+v::
SendInput {Raw}%Clipboard%
Return
; ctrl+alt+p for paste slowly - send delayed events from clipboard
^!p::
SetKeyDelay 100
SendEvent {Raw}%Clipboard%
Return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment