问题描述
有了 created a signed message,我不确定如何使用生成的签名来验证使用 publicKey 的消息。
我的用例是,我想使用 Solana 钱包以如下模式登录 API 服务器:
GET message: String (from API server)
sign message with privateKey
POST signature (to API server)
verify signature with stored publicKey
我尝试使用 nodeJS crypto.verify
来解码 API 端的签名消息,但我对缓冲区和椭圆曲线的深入研究有点超出:
// Front-end code
const toHexString = (buffer: Buffer) =>
buffer.reduce((str,byte) => str + byte.toString(16).padStart(2,"0"),"");
const data = new TextEncoder().encode('message to verify');
const signed = await wallet.sign(data,"hex");
await setLogin({ // sends API post call to backend
variables: {
publicAddress: walletPublicKey,signature: toHexString(signed.signature),},});
// Current WIP for backend code
const ALGORITHM = "ed25519";
const fromHexString = (hexString) =>
new Uint8Array(hexString.match(/.{1,2}/g).map((byte) => parseInt(byte,16)));
const signature = fromHexString(args.signature);
const nonceUint8 = new TextEncoder().encode('message to verify');
const verified = crypto.verify(
ALGORITHM,nonceUint8,`-----BEGIN PUBLIC KEY-----\n${user.publicAddress}\n-----END PUBLIC KEY-----`,signature
);
console.log("isverified: ",verified);
我很确定我以错误的方式解决这个问题,而且一定是我遗漏了一个明显的方法。
随着空间的成熟,我预计验证函数或库会消耗 const signed = await wallet.sign(data,"hex");
类似于:
import { VerifyMessage } from '@solana/web3.js';
const verified = VerifyMessage(message,publicKey,signature,'hex');
但是经过 3 天的努力,我开始达到我的极限并且我的大脑正在衰竭。任何帮助或指示在哪里看起来非常感谢?
解决方法
我建议留在 solana-labs trail 并使用 tweetnacl
spl-token-wallet (sollet.io) 用
nacl.sign.detached(message,this.account.secretKey)
另一方面,验证完成
nacl.sign.detached.verify
在@solana/web3.js https://github.com/solana-labs/solana/blob/master/web3.js/src/transaction.ts#L560
在后端使用 nacl.sign.detached.verify
应该会很好。我还建议避免任何数据格式操作,我不确定您要做什么,但如果您确实验证了每个步骤是否正确。
通过来自出色的 Project Serum discord 开发者的意见解决。高级解决方案是使用也在 sol-wallet-adapter 存储库中使用的库,即 tweetnacl
和 bs58
:
const signatureUint8 = base58.decode(args.signature);
const nonceUint8 = new TextEncoder().encode(user?.nonce);
const pubKeyUint8 = base58.decode(user?.publicAddress);
nacl.sign.detached.verify(nonceUint8,signatureUint8,pubKeyUint8)
// true