<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: Создание JWT с RS256 (RSA с SHA-256) для серверной Google Oauth2]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=17665</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=17665&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Создание JWT с RS256 (RSA с SHA-256) для серверной Google Oauth2».]]></description>
		<lastBuildDate>Sun, 12 Mar 2023 03:05:29 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[AHK: Создание JWT с RS256 (RSA с SHA-256) для серверной Google Oauth2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=157102#p157102</link>
			<description><![CDATA[<p><a href="https://developers.google.com/identity/protocols/oauth2/service-account">https://developers.google.com/identity/ … ce-account</a><br />Ключ должен быть сохранен как p12.<br /></p><div class="codebox"><pre><code>certificate := &quot;C:\blah-blah-blah\certain-haiku-23150.p12&quot;
privateKeyPassword := &quot;notasecret&quot;
clientEmail := &quot;service@certain-haik.gserviceaccount.com&quot;

DllCall(&quot;LoadLibrary&quot;, &quot;str&quot;, &quot;bcrypt.dll&quot;)
DllCall(&quot;LoadLibrary&quot;, &quot;str&quot;, &quot;ncrypt.dll&quot;)
DllCall(&quot;LoadLibrary&quot;, &quot;str&quot;, &quot;crypt32.dll&quot;)
time := A_NowUTC
EnvSub, time, 19700101000000, seconds
expTime := time+3600
header = {&quot;alg&quot;:&quot;RS256&quot;,&quot;typ&quot;:&quot;JWT&quot;}
payload = {&quot;iss&quot;:&quot;%clientEmail%&quot;,&quot;scope&quot;:&quot;https://www.googleapis.com/auth/prediction&quot;,&quot;aud&quot;:&quot;https://oauth2.googleapis.com/token&quot;,&quot;iat&quot;:%time%,&quot;exp&quot;:%expTime%}
header := Base64URLenc(header)
payload := Base64URLenc(payload)
file := FileOpen(certificate, &quot;r&quot;)
bufLen := file.rawRead(buffer, file.Length)
file.Close()
VarSetCapacity(CRYPT_INTEGER_BLOB, A_PtrSize*2, 0)
NumPut(bufLen, CRYPT_INTEGER_BLOB, 0, &quot;uint&quot;)
NumPut(&amp;buffer, CRYPT_INTEGER_BLOB, A_PtrSize, &quot;ptr&quot;)
hCertStore := DllCall(&quot;crypt32\PFXImportCertStore&quot;, &quot;ptr&quot;, &amp;CRYPT_INTEGER_BLOB, &quot;str&quot;, PrivateKeyPassword, &quot;uint&quot;, 0)
hContext := DllCall(&quot;crypt32\CertFindCertificateInStore&quot;, &quot;ptr&quot;, hCertStore, &quot;uint&quot;, (X509_ASN_ENCODING := 1)|(PKCS_7_ASN_ENCODING := 65536), &quot;uint&quot;, 0, &quot;uint&quot;, CERT_FIND_ANY := 0, &quot;ptr&quot;, 0, &quot;ptr&quot;, 0)
DllCall(&quot;crypt32\CryptAcquireCertificatePrivateKey&quot;, &quot;ptr&quot;, hContext, &quot;uint&quot;, CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG := 0x00040000, &quot;ptr&quot;, 0, &quot;ptr*&quot;, phKey, &quot;uint*&quot;, dwKeySpec, &quot;int*&quot;, bFreeHandle)
DllCall(&quot;bcrypt\BCryptOpenAlgorithmProvider&quot;, &quot;ptr*&quot;, hHashAlg, &quot;ptr&quot;, &amp;(BCRYPT_SHA256_ALGORITHM := &quot;SHA256&quot;), &quot;ptr&quot;, 0, &quot;uint&quot;, 0)
DllCall(&quot;bcrypt\BCryptOpenAlgorithmProvider&quot;, &quot;ptr*&quot;, hSignAlg, &quot;ptr&quot;, &amp;(BCRYPT_RSA_ALGORITHM := &quot;RSA&quot;), &quot;ptr&quot;, 0, &quot;uint&quot;, 0)
DllCall(&quot;bcrypt\BCryptCreateHash&quot;, &quot;ptr&quot;, hHashAlg, &quot;ptr*&quot;, hHash, &quot;ptr&quot;, 0, &quot;uint&quot;, 0, &quot;ptr&quot;, 0, &quot;uint&quot;, 0 , &quot;uint&quot;, 0)
size := StrPut(header &quot;.&quot; payload, &quot;UTF-8&quot;)
VarSetCapacity(pbInput, size, 0)
StrPut(header &quot;.&quot; payload, &amp;pbInput, &quot;UTF-8&quot;)
size--
DllCall(&quot;bcrypt\BCryptHashData&quot;, &quot;ptr&quot;, hHash, &quot;ptr&quot;, &amp;pbInput, &quot;uint&quot;, size, &quot;uint&quot;, 0)
DllCall(&quot;bcrypt\BCryptGetProperty&quot;, &quot;ptr&quot;, hHashAlg, &quot;ptr&quot;, &amp;(BCRYPT_HASH_LENGTH := &quot;HashDigestLength&quot;), &quot;uint*&quot;, cbHash, &quot;uint&quot;, 4, &quot;uint*&quot;, cbResult, &quot;uint&quot;, 0)
VarSetCapacity(pbHash, cbHash, 0)
DllCall(&quot;bcrypt\BCryptFinishHash&quot;, &quot;ptr&quot;, hHash, &quot;ptr&quot;, &amp;pbHash, &quot;uint&quot;, cbHash, &quot;uint&quot;, 0)
VarSetCapacity(BCRYPT_PKCS1_PADDING_INFO, A_PtrSize, 0)
NumPut(&amp;BCRYPT_SHA256_ALGORITHM, BCRYPT_PKCS1_PADDING_INFO)
DllCall(&quot;ncrypt\NCryptSignHash&quot;, &quot;ptr&quot;, phKey, &quot;ptr&quot;, &amp;BCRYPT_PKCS1_PADDING_INFO, &quot;ptr&quot;, &amp;pbHash, &quot;uint&quot;, cbHash, &quot;ptr&quot;, 0, &quot;uint&quot;, 0, &quot;uint*&quot;, cbSignature, &quot;uint&quot;, BCRYPT_PAD_PKCS1 := 2)
VarSetCapacity(pbSignature, cbSignature, 0)
DllCall(&quot;ncrypt\NCryptSignHash&quot;, &quot;ptr&quot;, phKey, &quot;ptr&quot;, &amp;BCRYPT_PKCS1_PADDING_INFO, &quot;ptr&quot;, &amp;pbHash, &quot;uint&quot;, cbHash, &quot;ptr&quot;, &amp;pbSignature, &quot;uint&quot;, cbSignature, &quot;uint*&quot;, cbSignature, &quot;uint&quot;, BCRYPT_PAD_PKCS1 := 2)
signature := Base64URLenc(&amp;pbSignature, cbSignature)
DllCall(&quot;bcrypt\BCryptDestroyHash&quot;, &quot;ptr&quot;, hHash)
DllCall(&quot;bcrypt\BCryptCloseAlgorithmProvider&quot;, &quot;ptr&quot;, hSignAlg, &quot;uint&quot;, 0)
DllCall(&quot;bcrypt\BCryptCloseAlgorithmProvider&quot;, &quot;ptr&quot;, hHashAlg, &quot;uint&quot;, 0)
DllCall(&quot;ncrypt\NCryptFreeObject&quot;, &quot;ptr&quot;, phKey)
DllCall(&quot;crypt32\CertFreeCertificateContext&quot;, &quot;ptr&quot;, hContext)
DllCall(&quot;crypt32\CertCloseStore&quot;, &quot;ptr&quot;, hCertStore, &quot;uint&quot;, CERT_CLOSE_STORE_FORCE_FLAG := 1)
jwt := header &quot;.&quot; payload &quot;.&quot; signature

HTTP := ComObjCreate(&quot;WinHTTP.WinHTTPRequest.5.1&quot;)
HTTP.Open(&quot;POST&quot;, &quot;https://oauth2.googleapis.com/token&quot;, true)
HTTP.SetRequestHeader(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;)
HTTP.Send(&quot;grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&amp;assertion=&quot; jwt)
HTTP.WaitForResponse()
msgbox % HTTP.ResponseText
return



Base64URLenc(pData, size := &quot;&quot;)
{
   if (size = &quot;&quot;)
   {
      VarSetCapacity(bin, StrPut(pData, &quot;UTF-8&quot;))
      size := StrPut(pData, &amp;bin, &quot;UTF-8&quot;) - 1
      pData := &amp;bin
   }
   DllCall(&quot;crypt32\CryptBinaryToString&quot;, &quot;ptr&quot;, pData, &quot;uint&quot;, size, &quot;uint&quot;, (CRYPT_STRING_BASE64 := 0x1)|(CRYPT_STRING_NOCRLF := 0x40000000), &quot;ptr&quot;, 0, &quot;uint*&quot;, chars)
   VarSetCapacity(outData, chars &lt;&lt; !!A_IsUnicode, 0)
   DllCall(&quot;crypt32\CryptBinaryToString&quot;, &quot;ptr&quot;, pData, &quot;uint&quot;, size, &quot;uint&quot;, (CRYPT_STRING_BASE64 := 0x1)|(CRYPT_STRING_NOCRLF := 0x40000000), &quot;str&quot;, outData, &quot;uint*&quot;, chars)
   outData := StrReplace(outData, &quot;=&quot;)
   outData := StrReplace(outData, &quot;+&quot;, &quot;-&quot;)
   outData := StrReplace(outData, &quot;/&quot;, &quot;_&quot;)
   return outData
}</code></pre></div><p>Ключ берется напрямую из json:<br /></p><div class="codebox"><pre><code>private_key := &quot;-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w04MZ4hUBGA2uOCWYXwDkCvA0ANd3n/EOU6sBGKMI3V98nCy5Gwxa9ObW2n\n+2VqcwBaNFC7Dok+XQBVMsE=\n-----END PRIVATE KEY-----\n&quot;
clientEmail := &quot;service@certain-haik.gserviceaccount.com&quot;

DllCall(&quot;LoadLibrary&quot;, &quot;str&quot;, &quot;bcrypt.dll&quot;)
DllCall(&quot;LoadLibrary&quot;, &quot;str&quot;, &quot;crypt32.dll&quot;)
time := A_NowUTC
EnvSub, time, 19700101000000, seconds
expTime := time+3600
header = {&quot;alg&quot;:&quot;RS256&quot;,&quot;typ&quot;:&quot;JWT&quot;}
payload = {&quot;iss&quot;:&quot;%clientEmail%&quot;,&quot;scope&quot;:&quot;https://www.googleapis.com/auth/prediction&quot;,&quot;aud&quot;:&quot;https://oauth2.googleapis.com/token&quot;,&quot;iat&quot;:%time%,&quot;exp&quot;:%expTime%}
header := Base64URLenc(header)
payload := Base64URLenc(payload)
private_key := StrReplace(private_key, &quot;\n&quot;)
len := CryptStringToBinary(private_key, outData)
DllCall(&quot;crypt32\CryptDecodeObjectEx&quot;, &quot;uint&quot;, (X509_ASN_ENCODING := 1)|(PKCS_7_ASN_ENCODING := 65536), &quot;int&quot;, PKCS_PRIVATE_KEY_INFO := 44, &quot;ptr&quot;, &amp;outData, &quot;uint&quot;, len, &quot;uint&quot;, (CRYPT_DECODE_ALLOC_FLAG := 0x8000)|(CRYPT_DECODE_NOCOPY_FLAG := 0x1), &quot;ptr&quot;, 0, &quot;ptr*&quot;, PrivateKeyInfo, &quot;uint*&quot;, cb)
PrivateKeyInfo_PrivateKey_cbData := numget(PrivateKeyInfo+0, 4*A_PtrSize, &quot;uint&quot;)
PrivateKeyInfo_PrivateKey_pbData := numget(PrivateKeyInfo+0, 5*A_PtrSize, &quot;uint&quot;)
DllCall(&quot;crypt32\CryptDecodeObjectEx&quot;, &quot;uint&quot;, (X509_ASN_ENCODING := 1)|(PKCS_7_ASN_ENCODING := 65536), &quot;int&quot;, CNG_RSA_PRIVATE_KEY_BLOB := 83, &quot;ptr&quot;, PrivateKeyInfo_PrivateKey_pbData, &quot;uint&quot;, PrivateKeyInfo_PrivateKey_cbData, &quot;uint&quot;, CRYPT_DECODE_ALLOC_FLAG := 0x8000, &quot;ptr&quot;, 0, &quot;ptr*&quot;, prkb, &quot;uint*&quot;, cb)
DllCall(&quot;LocalFree&quot;, &quot;ptr&quot;, PrivateKeyInfo)
DllCall(&quot;bcrypt\BCryptOpenAlgorithmProvider&quot;, &quot;ptr*&quot;, hSignAlg, &quot;ptr&quot;, &amp;(BCRYPT_RSA_ALGORITHM := &quot;RSA&quot;), &quot;ptr&quot;, 0, &quot;uint&quot;, 0)
DllCall(&quot;bcrypt\BCryptImportKeyPair&quot;, &quot;ptr&quot;, hSignAlg, &quot;ptr&quot;, 0, &quot;ptr&quot;, &amp;(BCRYPT_RSAPRIVATE_BLOB := &quot;RSAPRIVATEBLOB&quot;), &quot;ptr*&quot;, phKey, &quot;ptr&quot;, prkb, &quot;uint&quot;, cb, &quot;uint&quot;, 0)
DllCall(&quot;LocalFree&quot;, &quot;ptr&quot;, prkb)
DllCall(&quot;bcrypt\BCryptOpenAlgorithmProvider&quot;, &quot;ptr*&quot;, hHashAlg, &quot;ptr&quot;, &amp;(BCRYPT_SHA256_ALGORITHM := &quot;SHA256&quot;), &quot;ptr&quot;, 0, &quot;uint&quot;, 0)
DllCall(&quot;bcrypt\BCryptCreateHash&quot;, &quot;ptr&quot;, hHashAlg, &quot;ptr*&quot;, hHash, &quot;ptr&quot;, 0, &quot;uint&quot;, 0, &quot;ptr&quot;, 0, &quot;uint&quot;, 0 , &quot;uint&quot;, 0)
size := StrPut(header &quot;.&quot; payload, &quot;UTF-8&quot;)
VarSetCapacity(pbInput, size, 0)
StrPut(header &quot;.&quot; payload, &amp;pbInput, &quot;UTF-8&quot;)
size--
DllCall(&quot;bcrypt\BCryptHashData&quot;, &quot;ptr&quot;, hHash, &quot;ptr&quot;, &amp;pbInput, &quot;uint&quot;, size, &quot;uint&quot;, 0)
DllCall(&quot;bcrypt\BCryptGetProperty&quot;, &quot;ptr&quot;, hHashAlg, &quot;ptr&quot;, &amp;(BCRYPT_HASH_LENGTH := &quot;HashDigestLength&quot;), &quot;uint*&quot;, cbHash, &quot;uint&quot;, 4, &quot;uint*&quot;, cbResult, &quot;uint&quot;, 0)
VarSetCapacity(pbHash, cbHash, 0)
DllCall(&quot;bcrypt\BCryptFinishHash&quot;, &quot;ptr&quot;, hHash, &quot;ptr&quot;, &amp;pbHash, &quot;uint&quot;, cbHash, &quot;uint&quot;, 0)
VarSetCapacity(BCRYPT_PKCS1_PADDING_INFO, A_PtrSize, 0)
NumPut(&amp;BCRYPT_SHA256_ALGORITHM, BCRYPT_PKCS1_PADDING_INFO)
DllCall(&quot;bcrypt\BCryptSignHash&quot;, &quot;ptr&quot;, phKey, &quot;ptr&quot;, &amp;BCRYPT_PKCS1_PADDING_INFO, &quot;ptr&quot;, &amp;pbHash, &quot;uint&quot;, cbHash, &quot;ptr&quot;, 0, &quot;uint&quot;, 0, &quot;uint*&quot;, cbSignature, &quot;uint&quot;, BCRYPT_PAD_PKCS1 := 2)
VarSetCapacity(pbSignature, cbSignature, 0)
DllCall(&quot;bcrypt\BCryptSignHash&quot;, &quot;ptr&quot;, phKey, &quot;ptr&quot;, &amp;BCRYPT_PKCS1_PADDING_INFO, &quot;ptr&quot;, &amp;pbHash, &quot;uint&quot;, cbHash, &quot;ptr&quot;, &amp;pbSignature, &quot;uint&quot;, cbSignature, &quot;uint*&quot;, cbSignature, &quot;uint&quot;, BCRYPT_PAD_PKCS1 := 2)
signature := Base64URLenc(&amp;pbSignature, cbSignature)
DllCall(&quot;bcrypt\BCryptDestroyHash&quot;, &quot;ptr&quot;, hHash)
DllCall(&quot;bcrypt\BCryptCloseAlgorithmProvider&quot;, &quot;ptr&quot;, hSignAlg, &quot;uint&quot;, 0)
DllCall(&quot;bcrypt\BCryptCloseAlgorithmProvider&quot;, &quot;ptr&quot;, hHashAlg, &quot;uint&quot;, 0)
DllCall(&quot;bcrypt\BCryptDestroyKey&quot;, &quot;ptr&quot;, phKey)
jwt := header &quot;.&quot; payload &quot;.&quot; signature

HTTP := ComObjCreate(&quot;WinHTTP.WinHTTPRequest.5.1&quot;)
HTTP.Open(&quot;POST&quot;, &quot;https://oauth2.googleapis.com/token&quot;, true)
HTTP.SetRequestHeader(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;)
HTTP.Send(&quot;grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&amp;assertion=&quot; jwt)
HTTP.WaitForResponse()
msgbox % HTTP.ResponseText
return



Base64URLenc(pData, size := &quot;&quot;)
{
   if (size = &quot;&quot;)
   {
      VarSetCapacity(bin, StrPut(pData, &quot;UTF-8&quot;))
      size := StrPut(pData, &amp;bin, &quot;UTF-8&quot;) - 1
      pData := &amp;bin
   }
   DllCall(&quot;crypt32\CryptBinaryToString&quot;, &quot;ptr&quot;, pData, &quot;uint&quot;, size, &quot;uint&quot;, (CRYPT_STRING_BASE64 := 0x1)|(CRYPT_STRING_NOCRLF := 0x40000000), &quot;ptr&quot;, 0, &quot;uint*&quot;, chars)
   VarSetCapacity(outData, chars &lt;&lt; !!A_IsUnicode, 0)
   DllCall(&quot;crypt32\CryptBinaryToString&quot;, &quot;ptr&quot;, pData, &quot;uint&quot;, size, &quot;uint&quot;, (CRYPT_STRING_BASE64 := 0x1)|(CRYPT_STRING_NOCRLF := 0x40000000), &quot;str&quot;, outData, &quot;uint*&quot;, chars)
   outData := StrReplace(outData, &quot;=&quot;)
   outData := StrReplace(outData, &quot;+&quot;, &quot;-&quot;)
   outData := StrReplace(outData, &quot;/&quot;, &quot;_&quot;)
   return outData
}

CryptStringToBinary(string, ByRef outData)
{
   DllCall(&quot;Crypt32\CryptStringToBinary&quot;, &quot;ptr&quot;, &amp;string, &quot;uint&quot;, StrLen(string), &quot;uint&quot;, CRYPT_STRING_BASE64HEADER := 0, &quot;ptr&quot;, 0, &quot;uint*&quot;, bytes, &quot;uint*&quot;, 0, &quot;uint*&quot;, 0)
   VarSetCapacity(outData, bytes) 
   DllCall(&quot;Crypt32\CryptStringToBinary&quot;, &quot;ptr&quot;, &amp;string, &quot;uint&quot;, StrLen(string), &quot;uint&quot;, CRYPT_STRING_BASE64HEADER := 0, &quot;str&quot;, outData, &quot;uint*&quot;, bytes, &quot;uint*&quot;, 0, &quot;uint*&quot;, 0)
   Return bytes
}</code></pre></div><p><a href="http://forum.script-coding.com/viewtopic.php?id=16254">Тема для обсуждения</a></p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Sun, 12 Mar 2023 03:05:29 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=157102#p157102</guid>
		</item>
	</channel>
</rss>
