I'm fairly new to Nim, and I suspect I'm just doing something wrong here. I'm using Jester (for routing, etc) and Nimcrytpo (for hmac) but something isn't adding up. Here's how I'm attempting to verify a signature:
import jester
import dotenv
import os, strutils, times
import nimcrypto
const timestampHeader = "X-Slack-Request-Timestamp"
const slackSignatureHeader = "X-Slack-Signature"
const signatureVersion = "v0"
const signingSecret = os.getEnv("SLACK_SIGNING_SECRET")
proc isTimestampRecent(timestamp: int): bool =
abs(getTime().toUnix - timestamp) <= (60 * 5)
proc verifySignature*(request: Request): bool =
if (not request.headers.hasKey timestampHeader) or
(not request.headers.hasKey slackSignatureHeader):
return false
let timestamp = request.headers[timestampHeader].parseInt
if not timestamp.isTimestampRecent():
return false
let baseString = signatureVersion & ':' & $timestamp & ':' & $request.body
let mySignature = sha256.hmac(signingSecret, baseString)
let slackSignature = MDigest[256].fromHex(request.headers[slackSignatureHeader])
mySignature == slackSignature
A few things I'm running into:
- The signature doesn't match, and I'm not really sure how to debug that. I'm definitely getting a valid request from Slack and following the instructions for verification here: https://api.slack.com/authentication/verifying-requests-from-slack#about, but it's incorrect.
- I know I'm missing the
v0=in the comparison, but I'm not quite sure how to do that with the time independent comparison (whether I should be skipping that part or not in the comparison, etc)
My best guess at this point is that somehow the Jester/Httpbeast request body isn't "raw" enough (though it's just plain json...?) or is somehow processed.
Any help or suggestions on how to debug would be greatly appreciated. Thank you in advance!