You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js后端通过Aptos Typescript SDK验证签名

在Node.js后端验证Petra钱包的Aptos签名

我正在使用Petra钱包与Aptos Typescript SDK开发dApp,已在前端完成签名操作,但不清楚如何在Node.js后端验证签名。我尝试在官方文档及Github上查找方法,但未能找到。

环境信息:
前端依赖:

"@aptos-labs/ts-sdk": "^1.2.0",
    "@aptos-labs/wallet-adapter-react": "^2.1.2"

后端依赖:

"@aptos-labs/ts-sdk": "^1.2.0"

解决方案

步骤1:前端传递签名核心数据到后端

前端完成签名后,需要将原始待签名消息、钱包返回的签名值、用户Aptos地址(可选:直接传公钥以节省后端查询开销)这三类数据传给后端。

前端签名示例:

import { useWallet } from "@aptos-labs/wallet-adapter-react";

const { signMessage, account } = useWallet();

// 定义待签名消息(建议用结构化文本/JSON字符串,确保唯一性)
const rawMessage = `确认登录我的dApp,时间戳:${Date.now()}`;
const messageBytes = new TextEncoder().encode(rawMessage);

// 调用Petra钱包签名
const signResult = await signMessage({
  message: messageBytes,
  nonce: crypto.randomUUID(), // 加入随机串防止重放攻击
  address: account.address,
});

// 向后端发送验证请求
await fetch("/api/verify-aptos-signature", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    rawMessage,
    signature: signResult.signature,
    userAddress: account.address,
    userPublicKey: account.publicKey // 可选:直接传公钥,避免后端查节点
  }),
});

步骤2:Node.js后端验证签名

使用@aptos-labs/ts-sdk提供的Ed25519PublicKey和verifySignature工具完成验证,核心逻辑是用用户公钥校验签名与原始消息的匹配性。

后端验证示例:

import { Ed25519PublicKey, verifySignature, Hex, Aptos } from "@aptos-labs/ts-sdk";

// 初始化Aptos客户端(用于查询账户公钥,如果前端没传的话)
const aptosClient = new Aptos({ network: "testnet" }); // 按需切换主网/测试网

export async function POST(request: Request) {
  const { rawMessage, signature, userAddress, userPublicKey } = await request.json();

  try {
    // 获取用户公钥:优先用前端传递的,否则从Aptos节点查询
    const publicKeyHex = userPublicKey || (await aptosClient.getAccountInfo({ accountAddress: userAddress })).public_key;
    if (!publicKeyHex) throw new Error("无法获取用户公钥");

    // 转换公钥为SDK可处理的实例
    const publicKey = new Ed25519PublicKey(Hex.fromHexString(publicKeyHex));
    // 重新编码原始消息为字节数组(必须和前端编码方式一致)
    const messageBytes = new TextEncoder().encode(rawMessage);

    // 执行签名验证
    const isValid = verifySignature({
      publicKey,
      message: messageBytes,
      signature: Hex.fromHexString(signature),
    });

    return Response.json({
      success: isValid,
      message: isValid ? "签名验证通过" : "签名不匹配"
    }, { status: isValid ? 200 : 403 });
  } catch (error) {
    console.error("签名验证失败:", error);
    return Response.json({ success: false, message: "验证过程出错" }, { status: 500 });
  }
}

关键注意事项

  • 消息一致性:前后端必须使用完全相同的原始消息编码,比如前端用TextEncoder,后端也得用一样的方式,否则验证必失败。
  • 重放攻击防护:签名时加入随机nonce或时间戳,后端需记录已使用的nonce,避免同一签名被重复利用。
  • 性能优化:让前端直接传递公钥,省去后端查询Aptos节点的耗时。

内容的提问来源于stack exchange,提问作者Liki Crus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 04:20:12