Nim Slack 机器人签名验证问题
Nim Slack bot Signature Verification Issues
我对 Nim 还很陌生,我怀疑我只是在这里做错了什么。我正在使用 Jester(用于路由等)和 Nimcrytpo(用于 hmac),但有些东西没有加起来。以下是我尝试验证签名的方式:
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
我 运行 感兴趣的一些事情:
- 签名不匹配,我不太确定如何调试。我确实收到了来自 Slack 的有效请求,并按照此处的验证说明进行操作:https://api.slack.com/authentication/verifying-requests-from-slack#about,但它不正确。
- 我知道我在比较中遗漏了
v0=
,但我不太确定如何通过与时间无关的比较来做到这一点(我是否应该在比较中跳过那部分等)
此时我最好的猜测是 Jester/Httpbeast 请求正文在某种程度上不够“原始”(虽然它只是普通的 json...?)或者以某种方式被处理。
任何关于如何调试的帮助或建议将不胜感激。提前致谢!
折腾了一段时间,发现自己做错了很多事!希望这对其他人有帮助:
signingSecret
是从 env 中提取的,所以它不应该是一个常量——我把它移到了用 let
定义的过程本身中。
- headers 中的松弛签名以
v0=
为前缀,这使得 MDigest[256].fromHex()
的长度错误,因此最终成为空值(0000...
) 而不是应该的。
这是一个工作版本,以防其他人需要。如果您发现任何可以改进的地方,请告诉我。
import jester
import dotenv
import os, strutils, times
import nimcrypto
const timestampHeader = "X-Slack-Request-Timestamp"
const slackSignatureHeader = "X-Slack-Signature"
const signatureVersion = "v0"
proc isTimestampRecent(timestamp: int): bool =
abs(getTime().toUnix - timestamp) <= (60 * 5)
proc verifySignature*(request: Request): bool =
let signingSecret = os.getEnv("SLACK_SIGNING_SECRET")
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)
var rawSlackSignature: string = $request.headers[slackSignatureHeader]
rawSlackSignature.removePrefix(signatureVersion & '=')
let slackSignature = MDigest[256].fromHex(rawSlackSignature)
mySignature == slackSignature
我对 Nim 还很陌生,我怀疑我只是在这里做错了什么。我正在使用 Jester(用于路由等)和 Nimcrytpo(用于 hmac),但有些东西没有加起来。以下是我尝试验证签名的方式:
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
我 运行 感兴趣的一些事情:
- 签名不匹配,我不太确定如何调试。我确实收到了来自 Slack 的有效请求,并按照此处的验证说明进行操作:https://api.slack.com/authentication/verifying-requests-from-slack#about,但它不正确。
- 我知道我在比较中遗漏了
v0=
,但我不太确定如何通过与时间无关的比较来做到这一点(我是否应该在比较中跳过那部分等)
此时我最好的猜测是 Jester/Httpbeast 请求正文在某种程度上不够“原始”(虽然它只是普通的 json...?)或者以某种方式被处理。
任何关于如何调试的帮助或建议将不胜感激。提前致谢!
折腾了一段时间,发现自己做错了很多事!希望这对其他人有帮助:
signingSecret
是从 env 中提取的,所以它不应该是一个常量——我把它移到了用let
定义的过程本身中。- headers 中的松弛签名以
v0=
为前缀,这使得MDigest[256].fromHex()
的长度错误,因此最终成为空值(0000...
) 而不是应该的。
这是一个工作版本,以防其他人需要。如果您发现任何可以改进的地方,请告诉我。
import jester
import dotenv
import os, strutils, times
import nimcrypto
const timestampHeader = "X-Slack-Request-Timestamp"
const slackSignatureHeader = "X-Slack-Signature"
const signatureVersion = "v0"
proc isTimestampRecent(timestamp: int): bool =
abs(getTime().toUnix - timestamp) <= (60 * 5)
proc verifySignature*(request: Request): bool =
let signingSecret = os.getEnv("SLACK_SIGNING_SECRET")
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)
var rawSlackSignature: string = $request.headers[slackSignatureHeader]
rawSlackSignature.removePrefix(signatureVersion & '=')
let slackSignature = MDigest[256].fromHex(rawSlackSignature)
mySignature == slackSignature