if(__CRYPT__INIT==1)
return
if(!DllCall("Advapi32.dll\CryptAcquireContextW", "ptr*", __CRYPT__PROV, "ptr", 0, "wstr", "Microsoft Enhanced RSA and AES Cryptographic Provider" (A_OSVersion=="WIN_XP"?" (Prototype)":""), "uint", 24, "uint", 0xF0000000, "int"))
__CRYPT__PROV := 0
__CRYPT__INIT := 1
__CRYPT__LIST := {}
CryptGetKey(Key, KeySize=0, Algorithm="")
{
global __CRYPT__PROV, __CRYPT__LIST
if KeySize is not integer
{
Algorithm := KeySize
KeySize := StrLen(Key)
}
StringReplace, Algorithm, Algorithm,-,_, 1
StringUpper, Algorithm, Algorithm
pos := 1
Algo := ""
AlgoType := ""
AlgoHash := ""
KeyLen := 0
while((pos:=RegExMatch(Algorithm, "[\s,]*(\w+)", x, pos))>0)
{
pos += StrLen(x)
if(Algo=="")
{
if x1 in DES,3DES,3DES_112,DESX,RC2,SKIPJACK,TEK,CYLINK_MEK,RC5,AES_128,AES_192,AES_256
Algo := x1
else if(RegExMatch(x1, "^(RC4|SEAL)(?:_(\d+))?", y)>0)
{
Algo := y1
AlgoType := "none"
KeyLen := y2?y2:0
}
}
if(AlgoType=="")
{
if x1 in CBC,ECB,OFB,CFB,CTS
AlgoType := x1
}
if(AlgoHash=="")
{
if x1 in MD2,MD4,MD5,SHA,SHA1,MAC,SHA_256,SHA_384,SHA_512
AlgoHash := x1
}
}
if(Algo=="")
Algo := "AES_128"
if(AlgoType=="")
AlgoType := "CBC"
if(AlgoHash=="")
AlgoHash := "SHA_256"
Algo := Algo=="DES"?0x6601:Algo=="3DES_112"?0x6609:Algo=="3DES"?0x6603:Algo=="DESX"?0x6604:Algo=="RC2"?0x6602:Algo=="SKIPJACK"?0x660A:Algo=="TEK"?0x660B:Algo=="CYLINK_MEK"?0x660C:Algo=="RC5"?0x660D:Algo=="AES_128"?0x660E:Algo=="AES_192"?0x660F:Algo=="AES_256"?0x6610:Algo=="RC4"?0x6801:Algo=="SEAL"?0x6802:0
AlgoType := AlgoType=="CBC"?1:AlgoType=="ECB"?2:AlgoType=="OFB"?3:AlgoType=="CFB"?4:AlgoType=="CTS"?5:0
AlgoHash := AlgoHash=="MD2"?0x8001:AlgoHash=="MD4"?0x8002:AlgoHash=="MD5"?0x8003:AlgoHash=="SHA"?0x8004:AlgoHash=="SHA1"?0x8005:AlgoHash=="MAC"?0x8006:AlgoHash=="SHA_256"?0x800C:AlgoHash=="SHA_384"?0x800D:AlgoHash=="SHA_512"?0x800E:0
if(!DllCall("Advapi32.dll\CryptCreateHash", "ptr", __CRYPT__PROV, "uint", AlgoHash, "ptr", 0, "uint", 0, "ptr*", hHash, "int"))
return 0
if(!DllCall("Advapi32.dll\CryptHashData", "ptr", hHash, "astr", key, "uint", StrLen(key), "uint", 0, "int"))
goto l_fail
if(!DllCall("Advapi32.dll\CryptDeriveKey", "ptr", __CRYPT__PROV, "uint", Algo, "ptr", hHash, "uint", KeyLen<<16, "ptr*", hKey, "int"))
goto l_fail
if(AlgoType>0)
{
if(!DllCall("Advapi32.dll\CryptSetKeyParam", "ptr", hKey, "uint", 4, "uint*", AlgoType, "uint", 0, "int"))
goto l_fail
}
DllCall("Advapi32.dll\CryptDestroyHash", "ptr", hHash, "int")
x1 := 4
DllCall("Advapi32.dll\CryptGetKeyParam", "ptr", hKey, "uint", 8, "uint*", x, "uint*", x1, "uint", 0, "int")
__CRYPT__LIST.Insert(hKey, Mod(x, 8)>0?1:0+x//8)
return hKey
l_fail:
DllCall("Advapi32.dll\CryptDestroyHash", "ptr", hHash, "int")
return 0
}
CryptEncrypt(hKey, data, ByRef dataSize, BufSize=0, Final=1)
{
global __CRYPT__LIST
BlockSize := __CRYPT__LIST[hKey]
NewData := 0
if(BufSize==0)
{
if(BlockSize>0)
BufSize := BlockSize*(dataSize//BlockSize+1)
else
BufSize := dataSize
NewData := DllCall("msvcrt.dll\malloc", "ptr", BufSize, "ptr")
if(NewData==0)
return 0
DllCall("msvcrt.dll\memcpy", "ptr", NewData, "ptr", data, "ptr", dataSize, "ptr")
}
else
NewData := data
if(!DllCall("Advapi32.dll\CryptEncrypt", "ptr", hKey, "ptr", 0, "int", Final, "uint", 0, "ptr", NewData, "uint*", dataSize, "uint", BufSize, "int"))
return 0
return NewData
}
CryptEncryptStr(hKey, str, ByRef Size)
{
global __CRYPT__LIST
Len := StrLen(str)*2
BlockSize := __CRYPT__LIST[hKey]
if(BlockSize>0)
MaxLen := BlockSize*(Len//BlockSize+1)
else
MaxLen := Len
data := DllCall("msvcrt.dll\malloc", "ptr", MaxLen, "ptr")
StrPut(str, data, Len, "UTF-16")
ret := CryptEncrypt(hKey, data, Len, MaxLen)
Size := Len
return ret
}
CryptDecrypt(hKey, data, ByRef dataSize, Final=1)
{
if(!DllCall("Advapi32.dll\CryptDecrypt", "ptr", hKey, "ptr", 0, "int", Final, "uint", 0, "ptr", data, "uint*", dataSize, "int"))
return 0
return data
}
CryptDecryptStr(hKey, ByRef data, ByRef dataSize)
{
if(!DllCall("Advapi32.dll\CryptDecrypt", "ptr", hKey, "ptr", 0, "int", 1, "uint", 0, "ptr", data, "uint*", dataSize, "int"))
return 0
ret := StrGet(data, dataSize/2, "UTF-16")
free(data)
return ret
}
CryptHash(Algo, Data="", DataSize=-1, ReturnString=1)
{
global __CRYPT__PROV
ret := ReturnString==1?"":0
NewData := 0
if(DataSize==-1)
{
DataSize := StrLen(Data)*2
NewData := DllCall("msvcrt.dll\malloc", "ptr", DataSize, "ptr")
StrPut(Data, NewData, DataSize/2, "utf-16")
Data := NewData
}
StringReplace, Algo, Algo,-,_, 1
StringUpper, Algo, Algo
if(RegExMatch(Algo, "[\s,]*(MD2|MD4|MD5|SHA1|SHA_256|SHA_384|SHA_512|SHA)[\s,]*", x)>0)
Algo := x1
else
return ret
Algo := Algo=="MD2"?0x8001:Algo=="MD4"?0x8002:Algo=="MD5"?0x8003:Algo=="SHA"?0x8004:Algo=="SHA1"?0x8005:Algo=="MAC"?0x8006:Algo=="SHA_256"?0x800C:Algo=="SHA_384"?0x800D:Algo=="SHA_512"?0x800E:0
if(!DllCall("Advapi32.dll\CryptCreateHash", "ptr", __CRYPT__PROV, "uint", Algo, "ptr", 0, "uint", 0, "ptr*", hHash, "int"))
return ret
if(!DllCall("Advapi32.dll\CryptHashData", "ptr", hHash, "ptr", Data, "uint", DataSize, "uint", 0, "int"))
{
free(NewData)
DllCall("Advapi32.dll\CryptDestroyHash", "ptr", hHash, "int")
return ret
}
free(NewData)
DataSize := 4
DllCall("Advapi32.dll\CryptGetHashParam", "ptr", hHash, "uint", 4, "uint*", HashSize, "uint*", DataSize, "uint", 0, "int")
Hash := DllCall("msvcrt.dll\malloc", "ptr", HashSize, "ptr")
DllCall("Advapi32.dll\CryptGetHashParam", "ptr", hHash, "uint", 2, "ptr", Hash, "uint*", HashSize, "uint", 0, "int")
DllCall("Advapi32.dll\CryptDestroyHash", "ptr", hHash, "int")
if(ReturnString==1)
{
x := A_FormatInteger
SetFormat, Integer, H
loop %HashSize%
{
str := SubStr(NumGet(Hash|0, A_Index-1, "uchar"), 3, 2)
if(StrLen(str)==1)
str := "0" . str
ret .= str
}
SetFormat, Integer, %x%
free(Hash)
}
else
ret := Hash
return ret
}
free(ByRef data)
{
DllCall("msvcrt.dll\free", "ptr", data)
data := 0
}
CryptDelKey(hKey)
{
global __CRYPT__LIST
__CRYPT__LIST.Remove(hKey)
DllCall("Advapi32.dll\CryptDestroyKey", "ptr", hKey, "int")
}
CryptExit()
{
global __CRYPT__INIT, __CRYPT__LIST, __CRYPT__PROV
For key, value in __CRYPT__LIST
__CRYPT__LIST.Remove(key)
DllCall("Advapi32.dll\CryptReleaseContext", "ptr", __CRYPT__PROV, "uint", 0, "int")
__CRYPT__INIT := 0
}