目录
1.编写目的
2.工作原理
3.分析过程
3.1 websokcet连接
3.2 连接后的消息
3.3 获取sym_key
3.4 解密数据
Welcome to Code Block's blog
本篇文章主要介绍了
[WalletConnect协议数据解密]
❤博主广交技术好友,喜欢文章的可以关注一下❤
1.编写目的
最近在学习如何使用WalletConnect,查阅官方文档后,发现并没有太多的中文参考资料,英文直译读起来也有一些偏差,所以这边直接采用网页Demo的方式,对WC协议有了一定了解.在此进行记录,同时希望帮助到有实现相关功能的朋友.
2.工作原理
WC协议的工作原理其实就是用户wallet连接中继器,中继器连接网页或后端程序.首先,网页或后端程序会通过websocket使用jwt和注册的projectId连接到中继器,然后通过发布订阅的方式提交并生成wc链接,用户扫码后会链接到中继器,连接双方使用对称加密方式进行加密通信,以方便执行后续签名、授权操作。
3.分析过程
分析网址:https://react-app.walletconnect.com/
3.1 websokcet连接
打开这个网站,打开开发人员工具并找到网络选项,打开任意一个链并选择连接,可以在网络中发现一个websocket请求,内容如下:
wss://relay.walletconnect.com/?
auth={}&
projectId={}&
ua=wc-2%2Fjs-2.14.0%2Flinux-chrome-115.0.0%2Fbrowser%3Areact-app.walletconnect.com&
useOnCloseEvent=true这里有auth参数和projectId参数,分别是jwt Token和注册的ProjectId.后面两个作为可选参数,分别是ua即User-Agent:浏览器的相关标识,useOnCloseEvent可以指定为定时断连事件.下面是链接图:

3.2 连接后的消息
点击消息按钮即可查看当前websocket发送的消息,只关注点击连接后的两条上传消息.
第一条上传消息内容如下:
{
  "id": "1721369470072495872",
  "jsonrpc": "2.0",
  "method": "irn_subscribe",
  "params": {
    "topic": "ae450e4f4aa30817eee55d89d28e7ac63765a48c50dc4f84d5ad4512f8b1224c"
  }
}这里即订阅消息,订阅的topic为ae450e4f4aa30817eee55d89d28e7ac63765a48c50dc4f84d5ad4512f8b1224c 这个hex值会在生成钱包二维码时用到,作为会话标识.
第二条上传消息内容如下:
{
  "id": "1721392278452501504",
  "jsonrpc": "2.0",
  "method": "irn_publish",
  "params": {
    "topic": "ae450e4f4aa30817eee55d89d28e7ac63765a48c50dc4f84d5ad4512f8b1224c",
    "message": "AJvp7k0T4+B+dHCA32gyI+shaA9WNt6nJPjoCisvkyOEZ9riiRsV4olRVRyyC0sLSEfkYVk4eEVNWxxmPrCPjhX17vQ5M9JzDXIW6G/o1pzol7dd0IQZ2UbCsGUVx6vPLYjaIha2rpZZ5PVbFlshckUolTEjKYd2iMdTJyvUGUcwNAHftQAjyS+QUnEutbXvg43pvJBr05RfejqP6Ke9XvFoVIzqRlVuaIf67s8YLdg8G1G781zRt+78pxDJRLduAVXpNJyuWi3C+CEBXEAblrbrvf5nrXVwuffGlQNYHhXHEbszqaepbmweFjy6XKL0yM0Gpy7KW89a7ki9Tct5rWZzC6Aa5nkkbNtJ07VWZwIUC11bEkVEkYcsAtA9v73RApCxyXvtfUuUMwS7/vfYo7g8QMiZSdH5bSmz+OD9GLzmEauhHXgcwfkCehSStOc/v76kXHAnzjSHF0j15d4xPhk116Rqn7VyrMPces5T6eWP2Jpj1of18bBwvrqbSMVsk7TD+MIsMT01KuHzq1XAenuRFkSw3yHDwoMiDQFrJM/xyvriv/x9Vj7RBmTtDfp0ZXj7V4eDUV38l/Tb6T0C+sMtekUundmRizuZ8wWZM6ZpbPMRvydO1qOfC708g9Cn5rKoPoaLDK/JuBUK97iTTGeRxg0txtRuYp0+4nM58M4Q9RRj7qMkaQVLB/sFBQKp0scvEKXETz7L8/Zxt09jwlyk8gYRQpZhhDRjZkcp+N2LtcZaJMbadizxj4nGa+Ysv1vxQbBxUUzcRBk1W0TlgNpoZaYJv9+XJ+3Pq0N6nMF1irZhAaSGlksYV/OoJuPs2IhUIOrhWIOR2bWD6MnmKMlG0sT45A7mxedw+2DEmh4sMZ06B4O96fV/hWn7TywBD1aN1gMBUyApuNt/xLdFPcEk3Sp1VBQlbjv/p7anlXmFKyQzoa4q4BgipPJgrK6sXdTZU+exBsiBGkVieiaNUqIp2jS6nI2h2hjZDTWCtCyfUAsPUOczjtfqX9FvZNm4SuYo8Hx38tlxylEoUSKjKhrmF2fRUabwL9Ih6RJ2EBcHi5bDxnfh4ZBq1cV8HridNYLFSSa0+Zk6rlEI4DaEE6XPd7mIX+iQWwHgjyRdTTQ+tDHS5UnaFW7v75TxXo9syE/kmQf3Emg2HkfKjO1IOKwiUGCoD9pPezZ0BsmdfpPuQVAWOFiGmZk+cTq8ZcyFV4WE6rkYZkvZ0g/lbnI5n42LOUfx8x35ZFFA2NpRib58PxClw6AGTEdH5aCxMXA=",
    "ttl": 300,
    "prompt": true,
    "tag": 1100
  }
}这里的topic为对第一条中的订阅的topic.同时还有一个message信息,这个message即为使用ChaCha20Poly1305加密的数据。
3.3 获取sym_key
根据对称加密,用户钱包一定会获得一个密钥,这个密钥其实就是用户扫描的二维码数据内,我们使用除wallet外的其他任何应用的扫码功能去扫描点击连接后显示的二维码,得到wc协议数据,这里获取到的内容如下:
wc:ae450e4f4aa30817eee55d89d28e7ac63765a48c50dc4f84d5ad4512f8b1224c@2
?expiryTimestamp=1721392578&
relay-protocol=irn&
symKey=29630042945a25194e1500a42e9c62e10fa33cf5c462e71f17a317478a577f66wc协议的格式如下:
wc:{topic}@2?expiryTimestamp={}&relay-protocol=irn&symKey={}由此可知symKey为29630042945a25194e1500a42e9c62e10fa33cf5c462e71f17a317478a577f66 .其他参数分别是超时时间,转发协议.
注意:这里的topic一定是和上面的topic是一样的,如何不同说明不是一个会话.不同会话的symKey是不同的.
3.4 解密数据
我们上面获取到的消息体为:
AJvp7k0T4+B+dHCA32gyI+shaA9WNt6nJPjoCisvkyOEZ9riiRsV4olRVRyyC0sLSEfkYVk4eEVNWxxmPrCPjhX17vQ5M9JzDXIW6G/o1pzol7dd0IQZ2UbCsGUVx6vPLYjaIha2rpZZ5PVbFlshckUolTEjKYd2iMdTJyvUGUcwNAHftQAjyS+QUnEutbXvg43pvJBr05RfejqP6Ke9XvFoVIzqRlVuaIf67s8YLdg8G1G781zRt+78pxDJRLduAVXpNJyuWi3C+CEBXEAblrbrvf5nrXVwuffGlQNYHhXHEbszqaepbmweFjy6XKL0yM0Gpy7KW89a7ki9Tct5rWZzC6Aa5nkkbNtJ07VWZwIUC11bEkVEkYcsAtA9v73RApCxyXvtfUuUMwS7/vfYo7g8QMiZSdH5bSmz+OD9GLzmEauhHXgcwfkCehSStOc/v76kXHAnzjSHF0j15d4xPhk116Rqn7VyrMPces5T6eWP2Jpj1of18bBwvrqbSMVsk7TD+MIsMT01KuHzq1XAenuRFkSw3yHDwoMiDQFrJM/xyvriv/x9Vj7RBmTtDfp0ZXj7V4eDUV38l/Tb6T0C+sMtekUundmRizuZ8wWZM6ZpbPMRvydO1qOfC708g9Cn5rKoPoaLDK/JuBUK97iTTGeRxg0txtRuYp0+4nM58M4Q9RRj7qMkaQVLB/sFBQKp0scvEKXETz7L8/Zxt09jwlyk8gYRQpZhhDRjZkcp+N2LtcZaJMbadizxj4nGa+Ysv1vxQbBxUUzcRBk1W0TlgNpoZaYJv9+XJ+3Pq0N6nMF1irZhAaSGlksYV/OoJuPs2IhUIOrhWIOR2bWD6MnmKMlG0sT45A7mxedw+2DEmh4sMZ06B4O96fV/hWn7TywBD1aN1gMBUyApuNt/xLdFPcEk3Sp1VBQlbjv/p7anlXmFKyQzoa4q4BgipPJgrK6sXdTZU+exBsiBGkVieiaNUqIp2jS6nI2h2hjZDTWCtCyfUAsPUOczjtfqX9FvZNm4SuYo8Hx38tlxylEoUSKjKhrmF2fRUabwL9Ih6RJ2EBcHi5bDxnfh4ZBq1cV8HridNYLFSSa0+Zk6rlEI4DaEE6XPd7mIX+iQWwHgjyRdTTQ+tDHS5UnaFW7v75TxXo9syE/kmQf3Emg2HkfKjO1IOKwiUGCoD9pPezZ0BsmdfpPuQVAWOFiGmZk+cTq8ZcyFV4WE6rkYZkvZ0g/lbnI5n42LOUfx8x35ZFFA2NpRib58PxClw6AGTEdH5aCxMXA=symKey为:
29630042945a25194e1500a42e9c62e10fa33cf5c462e71f17a317478a577f66根据WalletConnect提供的ChaCha20Poly1305的消息格式为:
tp - type byte (1 byte) = 0
iv - initialization vector (12 bytes)
ct - ciphertext (N bytes)
tag - authentication tag (16 bytes)
sb - sealbox: ct + tag序列化消息格式为:
即将数据转换为bytes第0位为消息类型,1-13位长度12位数据位解密时用到的nonce,从13到最后为sealbox消息体.根据格式使用python对内容进行解密,代码如下:
# Base64 编码的密文字符串
base64_data = "AJvp7k0T4+B+dHCA32gyI+shaA9WNt6nJPjoCisvkyOEZ9riiRsV4olRVRyyC0sLSEfkYVk4eEVNWxxmPrCPjhX17vQ5M9JzDXIW6G/o1pzol7dd0IQZ2UbCsGUVx6vPLYjaIha2rpZZ5PVbFlshckUolTEjKYd2iMdTJyvUGUcwNAHftQAjyS+QUnEutbXvg43pvJBr05RfejqP6Ke9XvFoVIzqRlVuaIf67s8YLdg8G1G781zRt+78pxDJRLduAVXpNJyuWi3C+CEBXEAblrbrvf5nrXVwuffGlQNYHhXHEbszqaepbmweFjy6XKL0yM0Gpy7KW89a7ki9Tct5rWZzC6Aa5nkkbNtJ07VWZwIUC11bEkVEkYcsAtA9v73RApCxyXvtfUuUMwS7/vfYo7g8QMiZSdH5bSmz+OD9GLzmEauhHXgcwfkCehSStOc/v76kXHAnzjSHF0j15d4xPhk116Rqn7VyrMPces5T6eWP2Jpj1of18bBwvrqbSMVsk7TD+MIsMT01KuHzq1XAenuRFkSw3yHDwoMiDQFrJM/xyvriv/x9Vj7RBmTtDfp0ZXj7V4eDUV38l/Tb6T0C+sMtekUundmRizuZ8wWZM6ZpbPMRvydO1qOfC708g9Cn5rKoPoaLDK/JuBUK97iTTGeRxg0txtRuYp0+4nM58M4Q9RRj7qMkaQVLB/sFBQKp0scvEKXETz7L8/Zxt09jwlyk8gYRQpZhhDRjZkcp+N2LtcZaJMbadizxj4nGa+Ysv1vxQbBxUUzcRBk1W0TlgNpoZaYJv9+XJ+3Pq0N6nMF1irZhAaSGlksYV/OoJuPs2IhUIOrhWIOR2bWD6MnmKMlG0sT45A7mxedw+2DEmh4sMZ06B4O96fV/hWn7TywBD1aN1gMBUyApuNt/xLdFPcEk3Sp1VBQlbjv/p7anlXmFKyQzoa4q4BgipPJgrK6sXdTZU+exBsiBGkVieiaNUqIp2jS6nI2h2hjZDTWCtCyfUAsPUOczjtfqX9FvZNm4SuYo8Hx38tlxylEoUSKjKhrmF2fRUabwL9Ih6RJ2EBcHi5bDxnfh4ZBq1cV8HridNYLFSSa0+Zk6rlEI4DaEE6XPd7mIX+iQWwHgjyRdTTQ+tDHS5UnaFW7v75TxXo9syE/kmQf3Emg2HkfKjO1IOKwiUGCoD9pPezZ0BsmdfpPuQVAWOFiGmZk+cTq8ZcyFV4WE6rkYZkvZ0g/lbnI5n42LOUfx8x35ZFFA2NpRib58PxClw6AGTEdH5aCxMXA="
sym_key=bytes.fromhex("29630042945a25194e1500a42e9c62e10fa33cf5c462e71f17a317478a577f66")
chacha=ChaCha20Poly1305(sym_key)
# 解码 Base64 字符串
data = base64.b64decode(base64_data)
print(data)
# 提取 Type byte (1 byte)
tp = data[0]
# 提取 Initialization Vector (12 bytes)
iv = data[1:13]
# 提取 Sealbox (ct + tag)
sealbox = data[13:]
# 提取 Tag (16 bytes) 从 Sealbox
tag = sealbox[-16:]
# 提取 Ciphertext (ct)
ct = sealbox[:-16]
data=chacha.decrypt(nonce=iv,data=sealbox,associated_data=None)
print(f"解密数据:{data}")这样我们可以得到解密数据:
{
    "id": 1721392278449680,
    "jsonrpc": "2.0",
    "method": "wc_sessionPropose",
    "params": {
        "requiredNamespaces": {
            "solana": {
                "methods": [
                    "solana_signTransaction",
                    "solana_signMessage"
                ],
                "chains": [
                    "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
                    "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",
                    "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
                ],
                "events": [
                ]
            }
        },
        "optionalNamespaces": {
            "solana": {
                "methods": [
                ],
                "chains": [
                    "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
                    "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",
                    "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
                ],
                "events": [
                ]
            }
        },
        "relays": [
            {
                "protocol": "irn"
            }
        ],
        "proposer": {
            "publicKey": "e9965b8248e3bb68d98ec0d24a9ae9c922df3c89323017a65f63a043951a3e65",
            "metadata": {
                "description": "React App for WalletConnect",
                "url": "https://react-app.walletconnect.com",
                "icons": [
                    "https://avatars.githubusercontent.com/u/37784886"
                ],
                "name": "React App"
            }
        },
        "expiryTimestamp": 1721392578,
        "pairingTopic": "ae450e4f4aa30817eee55d89d28e7ac63765a48c50dc4f84d5ad4512f8b1224c"
    }
}我们使用二维码内的sym_key获取了websocket发送加密数据信息,这就证明wallectconnect确实如上面所说使用对称加密方式和用户钱包进行通信。
感谢关注,感谢点赞 !!








![苍穹外卖跟练项目前端localhost打不开页面启动nginx报错[alert] could not open error log file问题解决](https://i-blog.csdnimg.cn/direct/ea65952acc1846029b6d9ee59cfaa855.png)










