AutoHotkeyで暗号化(AES)を扱うコツ

特に暗号化後のバイナリ値の扱いで躓いたので、以下のソースを参考にしてみてください。
また、漢字も平気ですがAutoHotkeyのソース上では全角のAはダメ文字だったりしますので、そこは注意してください。

; AutoHotkeyでAES化して、暗号バイナリを 0xE8 なら "e8"のように見えるテキストにして、
; 保存、読み込み、 "e8"を 0xE8 にしてから、復号化して、元の文字列にする
; という一連の処理
; バイナリ文字列を得ても、文字列として扱う(関数に引数として渡す、関数の返値、コピー)では
; 途中に 0x00 があるとNULLとして扱うようで、それ以降を0x00の連続としてしまう・・・
; この点に注意が必要だった! (一日潰した・・・!)
; Crypt_AES()関数: https://autohotkey.com/board/topic/21913-aes-encryptdecrypt-of-a-file-in-wxp-or-higher/page-2
;
; 漢字も平気ですがAutoHotkeyのソース上では全角のAや柿などはダメ文字だったりしますので、そこは注意してください。
; ダメ文字の参考:http://blechmusik.hatenablog.jp/entry/20090725/1248455271
;
; 2017.3.26




Password = AutoHotkey

Data = 12345678901234567

Data_Len := StrLen(Data)

moto_text = %Data%0123456789abcdef ; allocate 16 byte more space

Encodeed_text := moto_text
Enc_size := Enc_AES(&Encodeed_text, Data_Len, Password, 256)
Encodeed_text := StrGet(&Encodeed_text, Enc_size)


/*
fw := FileOpen("c:\temp\test2.txt", "w")
fw.RawWrite(Encodeed_text, Enc_size)
fw.Close()

fr := FileOpen("c:\temp\test2.txt", "r")
fr.RawRead(Decoded_text, fr.Length)
fr.Close()
*/

;バイナリデータを変数に入れたものをユーザ定義関数へ渡す、となると、バイナリ値に 0x00 があると、それ以降は0x00で初期化したものを渡してしまう・・・
;なので、変数のアドレス渡し、の方法が必須となります。
Encoded_DXtext := text_to_DXtext(&Encodeed_text, Enc_size)


fw := FileOpen("c:\temp\test2.txt", "w")
tmp_text := Format("{1},{2}", Enc_size, Encoded_DXtext)
fw.WriteLine(tmp_text)
fw.Close()

fr := FileOpen("c:\temp\test2.txt", "r")
tmp_line := fr.ReadLine()
tmp_line := RegExReplace(tmp_line, "`n$")
fr.Close()
COMMA := ","
StringSplit, tmp_line_array, tmp_line, %COMMA%
Encoded_DXtext := tmp_line_array2
;msgbox, Encoded_DXtext : %Encoded_DXtext%
Encoded_size := StrLen(tmp_line_array2) / 2


VarSetCapacity(Decoded_text, Encoded_size)
DXtext_To_Text(&Decoded_text, Encoded_DXtext)
;test := StrGet(&Decoded_text, Encoded_size)
;msgbox, Decoded_text : %test% Encoded_size : %Encoded_size%
Dec_size := Dec_AES(&Decoded_text, Encoded_size, Password, 256)
Decoded_text := StrGet(&Decoded_text, Dec_size)
msgbox, Dec_size : %Dec_size% 復号後Decoded_text : %Decoded_text%
ExitApp







Enc_AES(pData, nSize, sPassword, SID = 256) {
ret := Crypt_AES(pData, nSize, sPassword, SID, 1)
Return, %ret%
}
Dec_AES(pData, nSize, sPassword, SID = 256) {
ret := Crypt_AES(pData, nSize, sPassword, SID, 0)
Return, %ret%
}



Crypt_AES(pData, nSize, sPassword, SID = 256, bEncrypt = True) {

CALG_AES_256 := 1 + CALG_AES_192 := 1 + CALG_AES_128 := 0x660E

CALG_SHA1 := 1 + CALG_MD5 := 0x8003

DllCall("advapi32\CryptAcquireContextA", "UintP", hProv, "Uint", 0, "str"

, "Microsoft Enhanced RSA and AES Cryptographic Provider" . (A_OSVersion="WIN_XP" ? " (Prototype)" : ""), "Uint", 24, "Uint", 0)

DllCall("advapi32\CryptCreateHash", "Uint", hProv, "Uint", CALG_SHA1, "Uint", 0, "Uint", 0, "UintP", hHash)

DllCall("advapi32\CryptHashData", "Uint", hHash, "Uint", &sPassword, "Uint", StrLen(sPassword), "Uint", 0)

DllCall("advapi32\CryptDeriveKey", "Uint", hProv, "Uint", CALG_AES_%SID%, "Uint", hHash, "Uint", SID<<16, "UintP", hKey)

DllCall("advapi32\CryptDestroyHash", "Uint", hHash)

If bEncrypt

DllCall("advapi32\CryptEncrypt", "Uint", hKey, "Uint", 0, "Uint", True, "Uint", 0, "Uint", pData, "UintP", nSize, "Uint", nSize+16)

Else DllCall("advapi32\CryptDecrypt", "Uint", hKey, "Uint", 0, "Uint", True, "Uint", 0, "Uint", pData, "UintP", nSize)

DllCall("advapi32\CryptDestroyKey", "Uint", hKey)

DllCall("advapi32\CryptReleaseContext", "Uint", hProv, "Uint", 0)

Return nSize

}

DecText_1(in_x){
if(in_x=="0" || in_x=="")
Return 0
if(in_x=="1")
Return 1
if(in_x=="2")
Return 2
if(in_x=="3")
Return 3
if(in_x=="4")
Return 4
if(in_x=="5")
Return 5
if(in_x=="6")
Return 6
if(in_x=="7")
Return 7
if(in_x=="8")
Return 8
if(in_x=="9")
Return 9
if(in_x=="A" || in_x=="a")
Return 10
if(in_x=="B" || in_x=="b")
Return 11
if(in_x=="C" || in_x=="c")
Return 12
if(in_x=="D" || in_x=="d")
Return 13
if(in_x=="E" || in_x=="e")
Return 14
if(in_x=="F" || in_x=="f")
Return 15

Return 0
}



text_to_DXtext(in_Ptext, in_length)
{
ret_text =
Loop, %in_length%
{
tmp_c := NumGet(in_Ptext+0, A_Index - 1, "UChar") ;StrGet(&in_text + A_Index - 1, 1)
tmp_DecText := Format("{1:02x}", tmp_c)
;MsgBox, tmp_c : %tmp_c% A_Index : %A_Index% tmp_DecText : %tmp_DecText%
ret_text .= tmp_DecText
}
Return, %ret_text%
}
DXtext_To_Text(in_Out_Ptext, in_text)
{
tmp_len := StrLen(in_text) / 2
Loop, %tmp_len%
{
tmp_c1 := StrGet(&in_text + (A_Index - 1) * 2 , 1)
tmp_c2 := StrGet(&in_text + (A_Index - 1) * 2 + 1, 1)
tmp_c_val := DecText_1(tmp_c1)*16 + DecText_1(tmp_c2)
tmp_c := chr(tmp_c_val)
NumPut(tmp_c_val, in_Out_Ptext+0, A_Index - 1, "UChar")
;test := StrGet(in_Out_Ptext, A_Index)
;msgbox, tmp_c_val : %tmp_c_val% test : %test%
}
;test := StrGet(in_Out_Ptext, tmp_len)
;msgbox, tmp_len : %tmp_len% test : %test%
Return, %ret_text%
}