Encrypt filenames?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
-Elaphe-
Posts: 75
Joined: 24 Dec 2020, 13:24

Encrypt filenames?

Post by -Elaphe- » 08 Jun 2023, 16:41

I have modified a script I've found for basic encryption of files. Now, I can select a bunch of files, use a hotkey and all of them will be encrypted. Using again the same hotkey over them will decrypt them. What I would like to add is the feature of also encrypting the filenames, so that they appear as a bunch of random numbers, for instance, instead of showing their real filenames. Of course, the hotkey should be able to restore, not only the contents, but also the original filenames. Any idea how to do this? I'm pasting the code I have for now, which is working correctly. Thankyou.

Code: Select all


#singleinstance force


GroupAdd,ExplorerGroup, ahk_class CabinetWClass
GroupAdd,ExplorerGroup, ahk_class ExploreWClass

Explorer_GetPath(hwnd="")
{
if !(window := Explorer_GetWindow(hwnd))
return ErrorLevel := "ERROR"
if (window="desktop")
return A_Desktop
path := window.LocationURL
path := RegExReplace(path, "ftp://.*@","ftp://")
StringReplace, path, path, file:///
StringReplace, path, path, /, \, All
Loop
If RegExMatch(path, "i)(?<=%)[\da-f]{1,2}", hex)
StringReplace, path, path, `%%hex%, % Chr("0x" . hex), All
Else Break
return path
}
Explorer_GetAll(hwnd="")
{
return Explorer_Get(hwnd)
}
Explorer_GetSelected(hwnd="")
{
return Explorer_Get(hwnd,true)
}
Explorer_GetWindow(hwnd="")
{
WinGet, process, processName, % "ahk_id" hwnd := hwnd? hwnd:WinExist("A")
WinGetClass class, ahk_id %hwnd%
if (process!="explorer.exe")
return
if (class ~= "(Cabinet|Explore)WClass")
{
for window in ComObjCreate("Shell.Application").Windows
if (window.hwnd==hwnd)
return window
}
else if (class ~= "Progman|WorkerW")
return "desktop"
}
Explorer_Get(hwnd="",selection=false)
{
if !(window := Explorer_GetWindow(hwnd))
return ErrorLevel := "ERROR"
if (window="desktop")
{
ControlGet, hwWindow, HWND,, SysListView321, ahk_class Progman
if !hwWindow
ControlGet, hwWindow, HWND,, SysListView321, A
ControlGet, files, List, % ( selection ? "Selected":"") "Col1",,ahk_id %hwWindow%
base := SubStr(A_Desktop,0,1)=="\" ? SubStr(A_Desktop,1,-1) : A_Desktop
Loop, Parse, files, `n, `r
{
path := base "\" A_LoopField
IfExist %path%
ret .= path "`n"
}
}
else
{
if selection
collection := window.document.SelectedItems
else
collection := window.document.Folder.Items
for item in collection
ret .= item.path "`n"
}
return Trim(ret,"`n")
}
return


<^<!<e::

IfWinActive ahk_group ExplorerGroup
{

inputfile =
inputfile := Explorer_GetSelected()

Loop, parse, inputfile, `n
{
filetoencrypt = %A_LoopField%

keyWord := "мой пароль"
keyLen := (StrPut(keyWord) - 1) << !!A_IsUnicode

; encrypt data
File := FileOpen(filetoencrypt, "r")
File.Pos := 0
len := File.RawRead(buff, File.Length)

Bcrypt(&buff, len, outData, &keyWord, keyLen,,, "RC4")

File := FileOpen(filetoencrypt, "w")
File.RawWrite(outData, len)
File := ""

}
}
return


Bcrypt(pData, dataSize, ByRef outData, pKey, keySize, pIv := 0, ivSize := 0, AlgId := "AES", crypt := "Decrypt", chainingMode := "ChainingModeCBC") {
; crypt: Encrypt/Decrypt
   static padding := BCRYPT_BLOCK_PADDING := 1, chainingModeSize := StrLen(chainingMode)*2
   pLocalIv := 0
   if pIv {
      VarSetCapacity(localIv, ivSize, 0)
      DllCall("RtlMoveMemory", "Ptr", pLocalIv := &localIv, "Ptr", pIv, "Ptr", ivSize)
   }
   DllCall("Bcrypt\BCryptOpenAlgorithmProvider", "PtrP", hAlgorithm, "WStr", AlgId, "Ptr", 0, "UInt", 0)
   DllCall("Bcrypt\BCryptSetProperty", "Ptr", hAlgorithm, "WStr", "ChainingMode"
                                                        , "WStr", chainingMode, "UInt", chainingModeSize, "UInt", 0)
   DllCall("Bcrypt\BCryptGenerateSymmetricKey", "Ptr", hAlgorithm, "PtrP", hKey, "Ptr", 0, "UInt", 0
                                                                 , "Ptr" , pKey, "UInt", keySize, "UInt", 0, "UInt")
   res := DllCall("Bcrypt\BCrypt" . crypt, "Ptr", hKey, "Ptr", pData, "UInt", dataSize, "Ptr", 0
                                                      , "Ptr", pLocalIv, "UInt", ivSize, "Ptr", 0
                                                      , "UInt", 0, "UIntP", outSize, "UInt", padding, "UInt")
   if (res != 0)
      throw "Crypt error! BCrypt" . crypt . "1 result: " . Format("{:#x}", res)
   VarSetCapacity(outData, outSize, 0)
   res := DllCall("Bcrypt\BCrypt" . crypt, "Ptr", hKey, "Ptr", pData, "UInt", dataSize, "Ptr", 0
                                                      , "Ptr", pLocalIv, "UInt", ivSize, "Ptr", &outData
                                                      , "UInt", outSize, "UIntP", outSize, "UInt", padding, "UInt")
   if (res != 0)
      throw "Crypt error! BCrypt" . crypt . "2 result: " . Format("{:#x}", res)
   DllCall("Bcrypt\BCryptDestroyKey", "Ptr", hKey)
   DllCall("Bcrypt\BCryptCloseAlgorithmProvider", "Ptr", hAlgorithm, "UInt", 0)
   Return outSize
}




-Elaphe-
Posts: 75
Joined: 24 Dec 2020, 13:24

Re: Encrypt filenames?

Post by -Elaphe- » 09 Jun 2023, 02:22

Another solution, in case the idea of encryption is too complicated, would be to change the letters of the filenames moving them some positions in the alphabet, for instance, a = c, b = d, c = e...

-Elaphe-
Posts: 75
Joined: 24 Dec 2020, 13:24

Re: Encrypt filenames?

Post by -Elaphe- » 09 Jun 2023, 04:37

OK, I've found the way to do it (the alphabetical renaming), together with the content encryption. I have to use 2 hotkeys because, although the code for the content encryption works as a toggle (the same hotkey works for encrypting and decrypting, as if it recognizes if the data is encrypted or not), I can't figure out a way to tell the renaming of files if the files are already renamed or have their original names. This is the code:

Code: Select all


#singleinstance force


GroupAdd,ExplorerGroup, ahk_class CabinetWClass
GroupAdd,ExplorerGroup, ahk_class ExploreWClass

Explorer_GetPath(hwnd="")
{
if !(window := Explorer_GetWindow(hwnd))
return ErrorLevel := "ERROR"
if (window="desktop")
return A_Desktop
path := window.LocationURL
path := RegExReplace(path, "ftp://.*@","ftp://")
StringReplace, path, path, file:///
StringReplace, path, path, /, \, All
Loop
If RegExMatch(path, "i)(?<=%)[\da-f]{1,2}", hex)
StringReplace, path, path, `%%hex%, % Chr("0x" . hex), All
Else Break
return path
}
Explorer_GetAll(hwnd="")
{
return Explorer_Get(hwnd)
}
Explorer_GetSelected(hwnd="")
{
return Explorer_Get(hwnd,true)
}
Explorer_GetWindow(hwnd="")
{
WinGet, process, processName, % "ahk_id" hwnd := hwnd? hwnd:WinExist("A")
WinGetClass class, ahk_id %hwnd%
if (process!="explorer.exe")
return
if (class ~= "(Cabinet|Explore)WClass")
{
for window in ComObjCreate("Shell.Application").Windows
if (window.hwnd==hwnd)
return window
}
else if (class ~= "Progman|WorkerW")
return "desktop"
}
Explorer_Get(hwnd="",selection=false)
{
if !(window := Explorer_GetWindow(hwnd))
return ErrorLevel := "ERROR"
if (window="desktop")
{
ControlGet, hwWindow, HWND,, SysListView321, ahk_class Progman
if !hwWindow
ControlGet, hwWindow, HWND,, SysListView321, A
ControlGet, files, List, % ( selection ? "Selected":"") "Col1",,ahk_id %hwWindow%
base := SubStr(A_Desktop,0,1)=="\" ? SubStr(A_Desktop,1,-1) : A_Desktop
Loop, Parse, files, `n, `r
{
path := base "\" A_LoopField
IfExist %path%
ret .= path "`n"
}
}
else
{
if selection
collection := window.document.SelectedItems
else
collection := window.document.Folder.Items
for item in collection
ret .= item.path "`n"
}
return Trim(ret,"`n")
}
return




<^<!<e::

IfWinActive ahk_group ExplorerGroup
{

inputfile =
inputfile := Explorer_GetSelected()

Loop, parse, inputfile, `n
{
filetoencrypt = %A_LoopField%

keyWord := "PassToEncrypt666!"
keyLen := (StrPut(keyWord) - 1) << !!A_IsUnicode

File := FileOpen(filetoencrypt, "r")
File.Pos := 0
len := File.RawRead(buff, File.Length)

Bcrypt(&buff, len, outData, &keyWord, keyLen,,, "RC4")

File := FileOpen(filetoencrypt, "w")
File.RawWrite(outData, len)
File := ""

SplitPath, A_LoopField,,directory,fileext,filename,
vText = %filename%.%fileext%

outputfile := JEE_StrCaesarCipher(vText, 2)
filemove, %A_LoopField%, %directory%\%outputfile% ,1

}
}
return




<^<!<d::

IfWinActive ahk_group ExplorerGroup
{

inputfile =
inputfile := Explorer_GetSelected()

Loop, parse, inputfile, `n
{
filetoencrypt = %A_LoopField%

keyWord := "PassToEncrypt666!"
keyLen := (StrPut(keyWord) - 1) << !!A_IsUnicode

File := FileOpen(filetoencrypt, "r")
File.Pos := 0
len := File.RawRead(buff, File.Length)

Bcrypt(&buff, len, outData, &keyWord, keyLen,,, "RC4")

File := FileOpen(filetoencrypt, "w")
File.RawWrite(outData, len)
File := ""

SplitPath, A_LoopField,,directory,fileext,filename,
vText = %filename%.%fileext%

outputfile := JEE_StrCaesarCipher(vText, -2)
filemove, %A_LoopField%, %directory%\%outputfile% ,1

}
}
return




Bcrypt(pData, dataSize, ByRef outData, pKey, keySize, pIv := 0, ivSize := 0, AlgId := "AES", crypt := "Decrypt", chainingMode := "ChainingModeCBC") {

   static padding := BCRYPT_BLOCK_PADDING := 1, chainingModeSize := StrLen(chainingMode)*2
   pLocalIv := 0
   if pIv {
      VarSetCapacity(localIv, ivSize, 0)
      DllCall("RtlMoveMemory", "Ptr", pLocalIv := &localIv, "Ptr", pIv, "Ptr", ivSize)
   }
   DllCall("Bcrypt\BCryptOpenAlgorithmProvider", "PtrP", hAlgorithm, "WStr", AlgId, "Ptr", 0, "UInt", 0)
   DllCall("Bcrypt\BCryptSetProperty", "Ptr", hAlgorithm, "WStr", "ChainingMode"
                                                        , "WStr", chainingMode, "UInt", chainingModeSize, "UInt", 0)
   DllCall("Bcrypt\BCryptGenerateSymmetricKey", "Ptr", hAlgorithm, "PtrP", hKey, "Ptr", 0, "UInt", 0
                                                                 , "Ptr" , pKey, "UInt", keySize, "UInt", 0, "UInt")
   res := DllCall("Bcrypt\BCrypt" . crypt, "Ptr", hKey, "Ptr", pData, "UInt", dataSize, "Ptr", 0
                                                      , "Ptr", pLocalIv, "UInt", ivSize, "Ptr", 0
                                                      , "UInt", 0, "UIntP", outSize, "UInt", padding, "UInt")
   if (res != 0)
      throw "Crypt error! BCrypt" . crypt . "1 result: " . Format("{:#x}", res)
   VarSetCapacity(outData, outSize, 0)
   res := DllCall("Bcrypt\BCrypt" . crypt, "Ptr", hKey, "Ptr", pData, "UInt", dataSize, "Ptr", 0
                                                      , "Ptr", pLocalIv, "UInt", ivSize, "Ptr", &outData
                                                      , "UInt", outSize, "UIntP", outSize, "UInt", padding, "UInt")
   if (res != 0)
      throw "Crypt error! BCrypt" . crypt . "2 result: " . Format("{:#x}", res)
   DllCall("Bcrypt\BCryptDestroyKey", "Ptr", hKey)
   DllCall("Bcrypt\BCryptCloseAlgorithmProvider", "Ptr", hAlgorithm, "UInt", 0)
   Return outSize
}




JEE_StrCaesarCipher(vText, vOffset)
{
	VarSetCapacity(vOutput, StrLen(vText)*2)
	Loop, Parse, vText
	{
		vTemp := A_LoopField
		vChar := Ord(vTemp)
		if JEE_Between(vChar, 97, 122)
		{
			vNum := Mod(vChar-97+vOffset, 26)
			if (vNum < 0)
				vNum += 26
			vChar2 := Chr(97+vNum)
		}
		else if JEE_Between(vChar, 65, 90)
		{
			vNum := Mod(vChar-65+vOffset, 26)
			if (vNum < 0)
				vNum += 26
			vChar2 := Chr(65+vNum)
		}
		else
			vChar2 := vTemp
		vOutput .= vChar2
	}
	return vOutput
}

JEE_Between(vNum, vLim1, vLim2, vOpt:="ii")
{
	if (vOpt = "ii") || (vOpt = "")
		return (vLim1 <= vNum && vNum <= vLim2)
	else if (vOpt = "xx")
		return (vLim1 < vNum && vNum < vLim2)
	else if (vOpt = "xi")
		return (vLim1 < vNum && vNum <= vLim2)
	else if (vOpt = "ix")
		return (vLim1 <= vNum && vNum < vLim2)
}


-Elaphe-
Posts: 75
Joined: 24 Dec 2020, 13:24

Re: Encrypt filenames?

Post by -Elaphe- » 03 Jul 2023, 11:40

I've found that the part of the script than encrypts / decrypts the content of the files doesn't work well with very large files. The error I get is "out of memory". Any way to fix that?

teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: Encrypt filenames?

Post by teadrinker » 03 Jul 2023, 19:10

#MaxMem 4095
Your code doesn't look correct. Use this way:

Code: Select all

#NoEnv
#MaxMem 4095
SetBatchLines, -1

password := "password"
iv := "salt" ; can be empty string
; encrypt file
CryptFile(A_ScriptFullPath, A_ScriptDir . "\encrypted.txt", password, iv)
; decrypt file
CryptFile(A_ScriptDir . "\encrypted.txt", A_ScriptDir . "\decrypted.txt", password, iv, false)

CryptFile(inFilePath, outFilePath, password, iv := "", crypt := true, algorithm := "AES", textEncoding := "UTF-8") {
; crypt: true — encrypt, false — decrypt
   File := FileOpen(inFilePath, "r")
   File.Pos := 0
   lenInData := File.RawRead(inData, File.Length)
   File.Close()
   
   hLib := DllCall("LoadLibrary", "Str", "Bcrypt.dll", "Ptr")
   lenPasswordData := StrPutBuff(password, passwordData, textEncoding)
   lenHashPassword := CreateHash(&passwordData, lenPasswordData, hashPassword)
   pHashIv := lenIv := 0
   if (iv != "") {
      lenIvData := StrPutBuff(iv, ivData, textEncoding)
      lenHashIv := CreateHash(&ivData, lenIvData, hashIv)
      VarSetCapacity(iv16, 16, 0)
      DllCall("RtlMoveMemory", "Ptr", pHashIv := &iv16, "Ptr", &hashIv + lenHashIv - 16, "Ptr", lenIv := 16)
   }
   crypt := (crypt ? "En" : "De") . "crypt"
   lenOutData := Bcrypt(&inData, lenInData, outData, &hashPassword, lenHashPassword, pHashIv, lenIv, algorithm, crypt)
   DllCall("FreeLibrary", "Ptr", hLib)
   
   File := FileOpen(outFilePath, "w", "cp0")
   File.RawWrite(outData, lenOutData)
   File.Close()
}

Bcrypt(pData, dataSize, ByRef outData, pKey, keySize, pIv := 0, ivSize := 0, AlgId := "AES", crypt := "Decrypt", chainingMode := "ChainingModeCBC") {
; crypt: Encrypt/Decrypt
   static padding := BCRYPT_BLOCK_PADDING := 1, chainingModeSize := StrLen(chainingMode)*2
   pLocalIv := 0
   if pIv {
      VarSetCapacity(localIv, ivSize, 0)
      DllCall("RtlMoveMemory", "Ptr", pLocalIv := &localIv, "Ptr", pIv, "Ptr", ivSize)
   }
   DllCall("Bcrypt\BCryptOpenAlgorithmProvider", "PtrP", hAlgorithm, "WStr", AlgId, "Ptr", 0, "UInt", 0)
   DllCall("Bcrypt\BCryptSetProperty", "Ptr", hAlgorithm, "WStr", "ChainingMode"
                                                        , "WStr", chainingMode, "UInt", chainingModeSize, "UInt", 0)
   DllCall("Bcrypt\BCryptGenerateSymmetricKey", "Ptr", hAlgorithm, "PtrP", hKey, "Ptr", 0, "UInt", 0
                                                                 , "Ptr" , pKey, "UInt", keySize, "UInt", 0, "UInt")
   res := DllCall("Bcrypt\BCrypt" . crypt, "Ptr", hKey, "Ptr", pData, "UInt", dataSize, "Ptr", 0
                                                      , "Ptr", pLocalIv, "UInt", ivSize, "Ptr", 0
                                                      , "UInt", 0, "UIntP", outSize, "UInt", padding, "UInt")
   if (res != 0)
      throw "Crypt error! BCrypt" . crypt . "1 result: " . Format("{:#x}", res)
   VarSetCapacity(outData, outSize, 0)
   res := DllCall("Bcrypt\BCrypt" . crypt, "Ptr", hKey, "Ptr", pData, "UInt", dataSize, "Ptr", 0
                                                      , "Ptr", pLocalIv, "UInt", ivSize, "Ptr", &outData
                                                      , "UInt", outSize, "UIntP", outSize, "UInt", padding, "UInt")
   if (res != 0)
      throw "Crypt error! BCrypt" . crypt . "2 result: " . Format("{:#x}", res)
   DllCall("Bcrypt\BCryptDestroyKey", "Ptr", hKey)
   DllCall("Bcrypt\BCryptCloseAlgorithmProvider", "Ptr", hAlgorithm, "UInt", 0)
   Return outSize
}

CreateHash(pData, size, ByRef hashData, pSecretKey := 0, keySize := 0, AlgId := "SHA256") {
   ; CNG Algorithm Identifiers
   ; https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-identifiers
   static HMAC := BCRYPT_ALG_HANDLE_HMAC_FLAG := 0x00000008
   DllCall("Bcrypt\BCryptOpenAlgorithmProvider", "PtrP", hAlgorithm, "WStr",  AlgId, "Ptr", 0, "UInt", keySize ? HMAC : 0)
   DllCall("Bcrypt\BCryptCreateHash", "Ptr", hAlgorithm, "PtrP", hHash, "Ptr", 0, "UInt", 0, "Ptr", pSecretKey, "UInt", keySize, "UInt", 0)
   DllCall("Bcrypt\BCryptHashData", "Ptr", hHash, "Ptr", pData, "UInt", size, "UInt", 0)
   DllCall("Bcrypt\BCryptGetProperty", "Ptr", hAlgorithm, "WStr", "HashDigestLength", "UIntP", hashLen, "UInt", 4, "UIntP", cbResult, "UInt", 0)
   VarSetCapacity(hashData, hashLen, 0)
   DllCall("Bcrypt\BCryptFinishHash", "Ptr", hHash, "Ptr", &hashData, "UInt", hashLen, "UInt", 0)
   DllCall("Bcrypt\BCryptDestroyHash", "Ptr", hHash)
   DllCall("Bcrypt\BCryptCloseAlgorithmProvider", "Ptr", hAlgorithm, "UInt", 0)
   Return hashLen
}

StrPutBuff(string, ByRef data, encoding := "UTF-8")  {
   VarSetCapacity( data, len := (StrPut(string, encoding) - 1) << (encoding ~= "i)^(UTF-16|cp1200)$") )
   StrPut(string, &data, encoding)
   Return len
}

Post Reply

Return to “Ask for Help (v1)”