According to the documentation at https://developers.google.com/accounts/docs/OAuth2ServiceAccount%|%Using OAuth 2.0 for Server to Server Applications%|% === The signing algorithm in the JWT header must be used when computing the signature. The only signing algorithm supported by the Google OAuth 2.0 Authorization Server is RSA using SHA-256 hashing algorithm. This is expressed as ‘RS256’ in the ‘alg’ field in the JWT header. Sign the UTF-8 representation of the input using SHA256withRSA (also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function) with the private key obtained from the Google Cloud Console. The output will be a byte array. === What is there in the tcl space that is equivalent to `SHA256withRSA (also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function)`? I was thinking that the `sha256` package would do the trick, but now I'm not so sure. Reason is that I took the signature block given on the developers.google.com page and did a `::base64::decode`. This gave me a string of assorted low and high ascii, which is not what I'm getting with a `::sha2::hmac` The goal is to be able to set up an OAuth2 connection to Google Analytics. I've already been to the https://cloud.google.com/console%|%Google Cloud Console%|% to set up the account, and get the various keys. The code I'm using is below. I'm still at the point where you generate the header. I haven't got to the HTTP stuff yet. ====== package require json package require sha256 package require base64 set h [open "client_secret.json" r] set d [read $h] close $h set mydd [dict create {*}[lindex [::json::json2dict $d] 1]] set header [string map {\n "" "=" ""} [::base64::encode "{\"alg\":\"RS256\",\"typ\":\"JWT\"}"]] set claims [string map {\n "" "=" ""} [::base64::encode "{\ \"iss\":\"[dict get $mydd client_email]\",\ \"scope\":\"https://www.googleapis.com/auth/analytics.readonly\",\ \"aud\":\"https://accounts.google.com/o/oauth2/token\",\ \"exp\":[expr [clock seconds] + 3600],\ \"iat\":[clock seconds]\ }"]] set signature "$header.$claims" set h [open "privatekey.p12" r] fconfigure $h -translation binary set d [read $h] close $h set sig [string map {\n "" "=" ""} [::base64::encode [::sha2::hmac $d $signature]]] set final "$signature.$sig" puts $final ====== [APN] See if http://core.tcl.tk/tcllib/doc/trunk/embedded/www/tcllib/files/modules/pki/pki.html#3%|%pki::sign%|% from the pki package in [tcllib] does what you want.