Last active
July 27, 2022 16:42
-
-
Save asmoore82/5113c990daedf3720d2dd7bf23bd4bde to your computer and use it in GitHub Desktop.
AutoHotKey script to use any clipboard manager to store encrypted passwords.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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