In the real world example, when the base64 encoded payload is hashed, I get a different value than the signature.
Payload: bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI= (newline omitted)
Signature: 2828aa29899722b35a2f191d34ef9b3ce695e0e6eeec47deb46d588d70c7cb56
My HMAC Hash (generated from devglan online tools): 1ce1494f94484b6f6a092be9b15ccc1cdafb1f8460a3838fbb0e0883c4390471
When I create a signature for the return URL, I get the same result as the website, so I am not quite sure why the answers do not match. If you are able to provide any insight into why this is, it would be greatly appreciated.
Also, you need to calculate the HMAC of the url-encoded base64 payload. So you should never be calculating the hash of a payload including a raw newline.
Instead, it should be %0A. If you’re using a web framework, bear in mind that it may have un-encoded the payload automatically. You will need to find a way to disable this, or re-encode the value.
I have not tested this on my website yet, I’m trying to work out the steps by hand before I do that.
From the forum post referenced earlier:
Given the following settings:
Discourse domain: http://discuss.example.com DiscourseConnect url : http://www.example.com/discourse/sso DiscourseConnect secret: d836444a9e4084d5b224a60c208dce14
User attempt to login
Nonce is generated: cb68251eefb5211e58c00ff1395f0c0b
Raw payload is generated: nonce=cb68251eefb5211e58c00ff1395f0c0b
Payload is Base64 encoded: bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI=\n
Payload is URL encoded: bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI%3D%0A
HMAC-SHA256 is generated on the Base64 encoded Payload: 2828aa29899722b35a2f191d34ef9b3ce695e0e6eeec47deb46d588d70c7cb56
Here is where I get a different answer. When I used a the HMAC encoder you suggested on the base64 non-URL encoded payload, I get d26d5adf900de48890a0c3dcdeec108acd91b44a4b76c90c59955a5ba7b957f7 instead of 2828aa29899722b35a2f191d34ef9b3ce695e0e6eeec47deb46d588d70c7cb56. When I use it on the URL encoded payload, I get 46e749cd26dcabc84eed323ff31f830da674dc87c77a2fcb1b296f76402ea900
However, later in the tutorial, during the creation of the new payload:
Unsigned payload is generated: nonce=cb68251eefb5211e58c00ff1395f0c0b&name=sam&username=samsam&email=test%40test.com&external_id=hello123&require_activation=true
(order does not matter, values are URL encoded)
Payload is Base64 encoded bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGImbmFtZT1zYW0mdXNlcm5hbWU9c2Ftc2FtJmVtYWlsPXRlc3QlNDB0ZXN0LmNvbSZleHRlcm5hbF9pZD1oZWxsbzEyMyZyZXF1aXJlX2FjdGl2YXRpb249dHJ1ZQ==
Payload is URL encoded bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGImbmFtZT1zYW0mdXNlcm5hbWU9c2Ftc2FtJmVtYWlsPXRlc3QlNDB0ZXN0LmNvbSZleHRlcm5hbF9pZD1oZWxsbzEyMyZyZXF1aXJlX2FjdGl2YXRpb249dHJ1ZQ%3D%3D
Base64 encoded Payload is signed 3d7e5ac755a87ae3ccf90272644ed2207984db03cf020377c8b92ff51be3abc3
This signature is generated from hashing the Base64 non-URL encoded payload, so that’s why I’m a little bit unsure of why it doesn’t work on the first payload.
On a hunch, I tried generating the signature for a string with a carriage return and a newline at the end (i.e. windows style line-endings), and managed to get the same signature as the freeformatter.com tool
Thanks for your suggestion! I coded parts of the process in JavaScript and when I tested them (with the nodeForge, urlencode, and js-base64 libraries) in RunKit, it returned the same thing as the tutorial.