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

如何验证sol-wallet-adapter生成的签名实现Solana钱包登录?

Solana钱包签名验证解决方案

核心错误原因

你调用Node原生crypto.verify失败的核心原因是:Solana钱包返回的公地址是base58编码的ed25519原始公钥字节,不是PEM格式的公钥,你直接套PEM头传入crypto.verify完全不匹配,自然验证失败。

最简实现方案

直接使用Solana生态通用的依赖组合实现,就是你预期的开箱即用逻辑:

第一步:安装依赖

npm install @solana/web3.js tweetnacl

第二步:后端验证代码

import { PublicKey } from '@solana/web3.js';
import nacl from 'tweetnacl';

// 16进制转Uint8Array工具函数,你之前的实现可直接复用
const fromHexString = (hexString) =>
  new Uint8Array(hexString.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));

// 封装好的验证方法,参数完全匹配你的预期
const verifySolanaSignature = (message, publicAddress, hexSignature) => {
  // 将base58编码的公地址转成原始公钥字节
  const publicKey = new PublicKey(publicAddress);
  // 解码16进制签名
  const signature = fromHexString(hexSignature);
  // 待验证消息转Uint8Array
  const messageUint8 = new TextEncoder().encode(message);
  
  // 直接调用ed25519签名验证
  return nacl.sign.detached.verify(messageUint8, signature, publicKey.toBytes());
}

// 调用示例
const verified = verifySolanaSignature('message to verify', user.publicAddress, args.signature);
console.log("isVerified: ", verified);

可选优化点

如果前端不想自行转换16进制,也可以直接将签名转成base58字符串传输,后端仅需把解码函数换成bs58.decode()即可,验证逻辑完全一致。

注意事项

  • 前后端待验证的消息必须完全一致,不能有任何字符、编码、空格、换行的差异
  • sol-wallet-adapter的sign方法默认返回的就是符合验证要求的原始签名字节,不需要额外处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 14:12:03