PHP验证TronWeb签名

  • Orange
  • 更新于 2022-12-28 16:32
  • 阅读 3212

PHP验证TronWeb签名

记录下PHP验证TRON签名的坑

Ethereum的验证有很多开源的代码,但是Tron的资料有用的很少,最后参考tronWeb库的代码爬出了深坑

https://github.com/tronprotocol/tronweb/blob/master/src/lib/trx.js#L630

区别:

Message Header Ethereum: \x19Ethereum Signed Message:\n Tron: \x19TRON Signed Message:\n32

Sign 结构 Ethereum: r,s Tron: recoveryParam, r ,s

废话不说上代码

    public function verify2(string $nonce, string $signature, string $address) : bool
    {
        $message = 'Welcome!\n\nThis request will not trigger a blockchain transaction or cost any gas fees.\n\nYour authentication status will reset after 24 hours.\n\nWallet address:'.$address.'\n\nNonce:' . $nonce;

        if(substr($address,2) == '0x'){
            $hash = Keccak::hash(sprintf("\x19Ethereum Signed Message:\n%s%s", strlen($message), $message), 256);
            $sign   = ['r' => substr($signature, 2, 64), 's' => substr($signature, 66, 64)];
        } else {
            $hash = Keccak::hash("\x19TRON Signed Message:\n32{$message}", 256);
            $sign = [
                'recoveryParam' => substr($signature, 130, 2) == '1c' ? 1 : 0,
                'r' => substr($signature, 2, 64),
                's' => substr($signature, 66, 64)
            ];
        }

        $recid  = ord(hex2bin(substr($signature, 130, 2))) - 27;

        if ($recid != ($recid & 1)) {
            return false;
        }

        $publicKey = (new EC('secp256k1'))->recoverPubKey($hash, $sign, $recid);

        if(substr($address,0,2) == '0x'){
            $recover_address =  '0x' . substr(Keccak::hash(substr(hex2bin($publicKey->encode('hex')), 1), 256), 24);
        } else {
            $recover_address =  '41' . substr(Keccak::hash(substr(hex2bin($publicKey->encode('hex')), 1), 256), 24);
            $address = (new Tron())->address2HexString($address);
        }

        return hash_equals($recover_address, $address);
    }
点赞 1
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Orange
Orange
0x3248...7bA5
一个初涉web3领域的程序员