Json Web Token Encoder in AutoHotKey

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
CotswoldsMaker
Posts: 12
Joined: 16 Dec 2020, 04:42

Json Web Token Encoder in AutoHotKey

18 Mar 2021, 15:50

Hi fellow programmers,

Anyone out there have experience with Json Web Tokens (JWT) as part of a REST API? I am trying to create a link between my AutoHotKey code and GOV.uk Notify. We are trying to send SMS and email messages to patients with links to patient information videos. I have been able to get a link and send SMS messages via the python code, which GOV.uk have kindly already created a library for. This has JWT built within it (well actually uses the pyJWT library). I have no idea how to build a JWT encoder to send my API messages. Anyone, with the remotest of chances, built a JWT library in AutoHotKey? If not, has anyone built an executable that I could give arguments to that itself could create a JWT? If not that, anyone able to talk me through how the JWT encoder works so that I can try to recreate it in AutoHotKey?

All help appreciated.

---------------------

Quick Bio: I am a medical doctor who also codes. Some call me a Hacktioner!
nadure
Posts: 22
Joined: 26 Mar 2021, 23:02
Location: Korea
Contact:

Re: Json Web Token Encoder in AutoHotKey

29 Mar 2021, 16:22

Hi. :wave:

Recently, I've just made it.

this is my origin blog.(not englinsh) :!:
https blog.naver.com /goglkms/222292001153 Broken Link for safety

and i'll explain it with english.

Code: Select all

#Include %A_ScriptDir%\Resource\JsonParser.ahk
#Include %A_ScriptDir%\Resource\libcrypt.ahk

JWT_Token(Header, Payload, SecretKey, mode="sha256")
{
    return new JWT_Token(Header, Payload, SecretKey, mode)
}

class JWT_Token
{
    __New(Header, Payload, SecretKey, mode="sha256")
    {
        ; Header -> Array()  ; Actually dict object. ex){"aa":"bbb"}
        ; Payload -> Array() ; Actually dict object. ex){"aa":"bbb"}
        ; SecretKey -> String ; just string for SecretKey
        this.TreatErrorthings(Header, Payload, SecretKey)
        Header_b64 := Base64enc(Json.Dump(Header))
        Payload_b64 := Base64enc(Json.Dump(Payload))
        Header_b64_url := Base64ToBase64URLenc(Header_b64)
        Payload_b64_url := Base64ToBase64URLenc(Payload_b64)

        message := Header_b64_url . "." . Payload_b64_url
        sign_origin := LC_HMAC(SecretKey, message, mode) ; ok good

        len:=CryptStringToBinary(sign_origin, outData, "CRYPT_STRING_HEXRAW")
        signature := CryptBinaryToString(&outData, len)
        signature := Base64ToBase64URLenc(signature)
        return Header_b64_url . "." . Payload_b64_url . "." . signature
    }

    TreatErrorthings(Header, Payload, SecretKey)
    {
        if(Header = "")
            throw, there is no Header String
        
        if(Payload = "")
            throw, there is no Payload String
        
        if(SecretKey="")
            throw, there is no SecretKey

        if(IsObject(Header) = false)
            throw, Header is not array

        if(IsObject(Payload) = false)
            throw, Header is not array
    }
}



Base64ToBase64URLenc(string)
{
    ; string -> base64

    ; string returnValue = System.Convert
    ;   .ToBase64String(toEncodeAsBytes)
    ;   .TrimEnd(padding).Replace('+', '-')
    ;   .Replace('/', '_');

    ; result := ""
    ; loop,% StrLen(string)
    ; {
    ;     sub_string := SubStr(string, -A_index, 1 )
    ;     if asc(sub_string) = 61
    ;     {   
    ;         result := SubStr(string, 1, StrLen(string)-A_Index-1)
    ;     }
    ;     else
    ;     {
    ;         if A_index = 1
    ;         {
    ;             result := string
    ;         }
    ;         break
    ;     }
    ; }

    result := StrReplace(string, "=", "")
    result := StrReplace(result, "+", "-")
    result := StrReplace(result, "/", "_")
    return result
}


Code(i) {   ; <== Chars[i & 63], 0-base index
   Static Chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
   Return SubStr(Chars,(i&63)+1,1)
}



Base64enc(string)
{
   Loop Parse, string
   {
      If Mod(A_Index,3) = 1
         buffer := Asc(A_LoopField) << 16
      Else If Mod(A_Index,3) = 2
         buffer += Asc(A_LoopField) << 8
      Else {
         buffer += Asc(A_LoopField)
         out := out . Code(buffer>>18) . Code(buffer>>12) . Code(buffer>>6) . Code(buffer)
      }
   }
   If Mod(StrLen(string),3) = 0
      Return out
   If Mod(StrLen(string),3) = 1
      Return out . Code(buffer>>18) . Code(buffer>>12) "=="
   Return out . Code(buffer>>18) . Code(buffer>>12) . Code(buffer>>6) "="
}

CryptStringToBinary(string, ByRef outData, formatName := "CRYPT_STRING_BASE64")
{
    ; https://www.autohotkey.com/boards/viewtopic.php?t=70358#p303866
   static formats := { CRYPT_STRING_BASE64: 0x1
                     , CRYPT_STRING_HEX:    0x4
                     , CRYPT_STRING_HEXRAW: 0xC }
   fmt := formats[formatName]
   DllCall( "Crypt32\CryptStringToBinary", "Ptr", &string, "UInt", StrLen(string), "UInt", fmt
                                         , "UInt", 0, "UIntP", bytes, "UIntP", 0, "UIntP", 0 )
   VarSetCapacity(outData, bytes) 
   DllCall( "Crypt32\CryptStringToBinary", "Ptr", &string, "UInt", StrLen(string), "UInt", fmt
                                         , "Str", outData, "UIntP", bytes, "UIntP", 0, "UIntP", 0 )
   Return bytes
}

CryptBinaryToString(pData, size, formatName := "CRYPT_STRING_BASE64", NOCRLF := true)
{
    ; https://www.autohotkey.com/boards/viewtopic.php?t=70358#p303866
   static formats := { CRYPT_STRING_BASE64: 0x1
                     , CRYPT_STRING_HEX:    0x4
                     , CRYPT_STRING_HEXRAW: 0xC }
        , CRYPT_STRING_NOCRLF := 0x40000000
   fmt := formats[formatName] | (NOCRLF ? CRYPT_STRING_NOCRLF : 0)
   DllCall("Crypt32\CryptBinaryToString", "Ptr", pData, "UInt", size, "UInt", fmt, "Ptr", 0, "UIntP", chars)
   VarSetCapacity(outData, chars << !!A_IsUnicode)
   DllCall("Crypt32\CryptBinaryToString", "Ptr", pData, "UInt", size, "UInt", fmt, "Str", outData, "UIntP", chars)
   Return outData
}
libcrypt
https://github.com/ahkscript/libcrypt.ahk

JsonParser
https://github.com/cocobelgica/AutoHotkey-JSON


at the below, this is an working example code.

Code: Select all

#SingleInstance, Force
SendMode Input
SetWorkingDir, %A_ScriptDir%
#Include Resource\JWT_Token.ahk


Header := {"alg":"HS256", "typ":"JWT"}
Payload := {"sub":"1234567890", "name":"John Doe", "iat":"1516239022"}
key:= "your-256-bit-secret"

Msgbox,% JWT_Token(Header, Payload, key)
clipboard := JWT_Token(Header, Payload, key)
return
If you are passing Header or Payload Its var type is must be Array object.
and key's type is String.

verified img
Image Broken Link for safety
Image Broken Link for safety

It's not hard. :wave:

Cheers!
Last edited by nadure on 01 Apr 2021, 09:40, edited 3 times in total.
nadure
Posts: 22
Joined: 26 Mar 2021, 23:02
Location: Korea
Contact:

Re: Json Web Token Encoder in AutoHotKey(JWT Library)

29 Mar 2021, 16:27

for other people who using JWT keword for searching, I 've just added title.
:wave:

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Tech Stuff, Vanda_a and 371 guests