DiscourseConnect codifica payload hash non corrispondente

Ciao,

sono nuovo nel lavoro con Discourse e AWS, quindi speravo che qualcuno potesse aiutarmi o indicarmi la direzione giusta. Sto cercando di configurare DiscourseConnect con il mio sito web, seguendo le istruzioni su questo forum https://meta.discourse.org/t/discourseconnect-official-single-sign-on-for-discourse-sso/13045/1

Nell’esempio pratico, quando il payload codificato in base64 viene hashato, ottengo un valore diverso dalla firma.
Payload: bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI= (a capo omesso)
Firma: 2828aa29899722b35a2f191d34ef9b3ce695e0e6eeec47deb46d588d70c7cb56
Il mio hash HMAC (generato con gli strumenti online di devglan): 1ce1494f94484b6f6a092be9b15ccc1cdafb1f8460a3838fbb0e0883c4390471

Quando creo una firma per l’URL di ritorno, ottengo lo stesso risultato del sito web, quindi non sono del tutto sicuro del motivo per cui le risposte non coincidono. Se siete in grado di fornire qualche chiarimento sul perché ciò accada, ve ne sarei molto grato.

Puoi condividere un esempio di payload, l’hash che ottieni e il segreto? (assicurati di cambiare il segreto sul tuo sito di test prima di pubblicarlo qui)

Le nuove righe sono importanti e influenzeranno la firma. Sembra che HMAC-SHA256 Generator Online rimuova le nuove righe prima di calcolare l’hash. Potresti avere più fortuna con un altro strumento come Free Online HMAC Generator / Checker Tool (MD5, SHA-256, SHA-512) - FreeFormatter.com

Inoltre, devi calcolare l’HMAC del payload url-encoded in base64. Quindi non dovresti mai calcolare l’hash di un payload che include una nuova riga grezza.

Invece, dovrebbe essere %0A. Se stai utilizzando un framework web, tieni presente che potrebbe aver decodificato automaticamente il payload. Dovrai trovare un modo per disabilitare questa funzionalità o ricodificare il valore.

3 Mi Piace

Non ho ancora testato questo sul mio sito web; sto cercando di capire i passaggi a mano prima di farlo.

Dal post del forum citato in precedenza:

Dati i seguenti impostazioni:
Dominio di Discourse: http://discuss.example.com
URL di DiscourseConnect: http://www.example.com/discourse/sso
Segreto di DiscourseConnect: d836444a9e4084d5b224a60c208dce14

Tentativo di accesso dell’utente

  • Viene generato un nonce: cb68251eefb5211e58c00ff1395f0c0b
  • Viene generato il payload grezzo: nonce=cb68251eefb5211e58c00ff1395f0c0b
  • Il payload viene codificato in Base64: bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI=\n
  • Il payload viene codificato in URL: bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI%3D%0A
  • Viene generato un HMAC-SHA256 sul payload codificato in Base64: 2828aa29899722b35a2f191d34ef9b3ce695e0e6eeec47deb46d588d70c7cb56

Qui ottengo una risposta diversa. Quando ho utilizzato il codificatore HMAC che hai suggerito sul payload in Base64 non codificato in URL, ho ottenuto d26d5adf900de48890a0c3dcdeec108acd91b44a4b76c90c59955a5ba7b957f7 invece di 2828aa29899722b35a2f191d34ef9b3ce695e0e6eeec47deb46d588d70c7cb56. Quando lo uso sul payload codificato in URL, ottengo 46e749cd26dcabc84eed323ff31f830da674dc87c77a2fcb1b296f76402ea900.

Tuttavia, più avanti nel tutorial, durante la creazione del nuovo payload:

Viene generato il payload non firmato:
nonce=cb68251eefb5211e58c00ff1395f0c0b&name=sam&username=samsam&email=test%40test.com&external_id=hello123&require_activation=true
(l’ordine non importa, i valori sono codificati in URL)

Il payload viene codificato in Base64:
bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGImbmFtZT1zYW0mdXNlcm5hbWU9c2Ftc2FtJmVtYWlsPXRlc3QlNDB0ZXN0LmNvbSZleHRlcm5hbF9pZD1oZWxsbzEyMyZyZXF1aXJlX2FjdGl2YXRpb249dHJ1ZQ==

Il payload viene codificato in URL:
bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGImbmFtZT1zYW0mdXNlcm5hbWU9c2Ftc2FtJmVtYWlsPXRlc3QlNDB0ZXN0LmNvbSZleHRlcm5hbF9pZD1oZWxsbzEyMyZyZXF1aXJlX2FjdGl2YXRpb249dHJ1ZQ%3D%3D

Il payload codificato in Base64 viene firmato:
3d7e5ac755a87ae3ccf90272644ed2207984db03cf020377c8b92ff51be3abc3

Questa firma viene generata dall’hashing del payload in Base64 non codificato in URL, ecco perché sono un po’ incerto sul motivo per cui non funziona sul primo payload.

Interessante! Anche io non riesco a replicare la firma usando quel generatore online. In Ruby, posso fare questo, che funziona come previsto:

pry(main)> OpenSSL::HMAC.hexdigest("sha256", "d836444a9e4084d5b224a60c208dce14", "bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI=\n")
=> "2828aa29899722b35a2f191d34ef9b3ce695e0e6eeec47deb46d588d70c7cb56"

Per un’intuizione, ho provato a generare la firma per una stringa con un ritorno a capo e un’a capo alla fine (cioè interruzioni di riga in stile Windows), e sono riuscito a ottenere la stessa firma dello strumento freeformatter.com

pry(main)> OpenSSL::HMAC.hexdigest("sha256", "d836444a9e4084d5b224a60c208dce14", "bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI=\r\n")
=> "200c03f1e5d7b859170be102b436d74f761040261be9682b4afec67eb908fabf"

Quindi penso che la cosa migliore sia evitare questi strumenti online e provare un’implementazione minima nel linguaggio di programmazione che intendi utilizzare.

6 Mi Piace

Grazie per il tuo suggerimento! Ho codificato alcune parti del processo in JavaScript e, quando le ho testate (con le librerie nodeForge, urlencode e js-base64) in RunKit, hanno restituito lo stesso risultato del tutorial.

3 Mi Piace