如何在 deno 中使用 HmacSHA256 创建(并验证)哈希?

问题描述 投票:0回答:2

我知道如何在 Python 中做到这一点。

#!/usr/bin/python
import sys
import os
import hashlib
import hmac
import base64

secretKey = bytes("passw@rd", 'UTF-8')
message = bytes(f'hello world\nhello deno', 'UTF-8')
encryptedKey = base64.b64encode(hmac.new(secretKey, message, digestmod=hashlib.sha256).digest())
print(encryptedKey)

code output

但我不知道如何在 deno 中做到这一点。 我希望在 deno 中得到与上面的 python 代码相同的结果。

typescript hash deno
2个回答
5
投票

您可以借助内置 crypto.subtle 工具(自 2021 年中期开始提供)创建 HMAC-SHA256 哈希,如下所示:

import { encode, decode } from "https://deno.land/std/encoding/base64.ts"

// just an example of the data for which we create an HMAC
const message = "hello world\nhello deno"

const encoder = new TextEncoder()

const secretKey = "passw@rd";
const keyBuf = encoder.encode(secretKey);

const key = await crypto.subtle.importKey(
  "raw",
  keyBuf,
  {name: "HMAC", hash: "SHA-256"},
  true,
  ["sign", "verify"],
)

const data = encoder.encode(message);
const result = await crypto.subtle.sign("HMAC", key , data.buffer);
console.log(encode(new Uint8Array(result)));

kqfsOD/HMHBRL9F1Si4Y/qo9PCw2csuwXIGZK/P1IWc=

如果目标只是验证现有签名,您可以将解码后的签名传递给

verify
函数:

// validation of a received hmac-code
const hmacBase64 = "kqfsOD/HMHBRL9F1Si4Y/qo9PCw2csuwXIGZK/P1IWc=";

const hmacDecoded = decode(hmacBase64); // Base64 decoding

const verified = await crypto.subtle.verify("HMAC", key, hmacDecoded, data.buffer);
console.log("The signature is " + (verified? "": "in") + "valid");

签名有效


在 Deno 中引入 crypto.subtle 之前,有两种基于外部包的选择:

您可以使用 God Crypto 来实现,但这需要额外的 Base64 模块。重要提示:God Crypto 所有者已停止维护该软件包,因此不建议再使用。

import { hmac } from "https://deno.land/x/[email protected]/mod.ts"
import * as base64 from "https://deno.land/x/[email protected]/mod.ts"

let secretKey = "passw@rd"
let message = "hello world\nhello deno"

const result: string = base64.fromUint8Array(hmac("sha256", secretKey, message))

console.log(result)

kqfsOD/HMHBRL9F1Si4Y/qo9PCw2csuwXIGZK/P1IWc=

或者您可以使用更方便的 hmac 模块,它集成了“base64”、“utf8”和“hex”的输出编码:

import { hmac } from "https://deno.land/x/[email protected]/mod.ts";

let secretKey = "passw@rd"
let message = "hello world\nhello deno"

const result = hmac("sha256", secretKey , message , "utf8", "base64");
console.log(result)

kqfsOD/HMHBRL9F1Si4Y/qo9PCw2csuwXIGZK/P1IWc=


0
投票

这里是十六进制 HMAC 密钥的示例,用于使用 Deno 验证交互式 Slack 请求。

可以在此处找到验证 Slack 请求的 HMAC 签名的通用说明:https://api.slack.com/authentication/verifying-requests-from-slack

import { createHmac } from "https://deno.land/[email protected]/node/crypto.ts";
import { config } from "https://deno.land/x/dotenv/mod.ts";

export const verifySlackRequest = async (event): Promise<boolean> => {
    try {
        const slackSigningSecret = config().SLACK_SIGNING_SECRET ||
            Deno.env.get("SLACK_SIGNING_SECRET");
        const timestamp = event.headers["X-Slack-Request-Timestamp"];
    // compare timestamp to current time to prevent replay attacks 
    // (if more than 5 minutes difference, reject request)
        if (Math.abs(Date.now() / 1000 - timestamp) > 60 * 5) {
            return false;
        }

        const requestBody = await event.body;
        const sigBasestring = `v0:${timestamp}:${requestBody}`;

        const mySignature = `v0=${createHmac("sha256", slackSigningSecret).update(sigBasestring).digest("hex")}`
        const slackSignature = event.headers["X-Slack-Signature"];
    // v0=b3d6055fd34da90b1174b678670d91fa0470da8b57c1a6ef82749cc9ec1ec6b3
        
    // it would be better to compare signatures using an HMAC utility, 
    // but I haven't found one for Deno.
        const isVerified = mySignature === slackSignature;
        return isVerified;
    } catch (error) {
        console.log('error:', JSON.stringify(error))
        return false;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.