小试牛刀-区块链WalletConnect协议数据解密

简介: 最近在学习如何使用Wallet Connect,查阅官方文档后,发现并没有太多的中文参考资料,英文直译读起来也有一些偏差,所以这边直接采用网页Demo的方式,对WC协议有了一定了解.在此进行记录,同时希望帮助到有实现相关功能的朋友.

 目录

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

image.gif

       这里有auth参数和projectId参数,分别是jwt Token和注册的ProjectId.后面两个作为可选参数,分别是ua即User-Agent:浏览器的相关标识,useOnCloseEvent可以指定为定时断连事件.下面是链接图:

image.gif 编辑

3.2  连接后的消息

       点击消息按钮即可查看当前websocket发送的消息,只关注点击连接后的两条上传消息.

第一条上传消息内容如下:

{
  "id": "1721369470072495872",
  "jsonrpc": "2.0",
  "method": "irn_subscribe",
  "params": {
    "topic": "ae450e4f4aa30817eee55d89d28e7ac63765a48c50dc4f84d5ad4512f8b1224c"
  }
}

image.gif

       这里即订阅消息,订阅的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
  }
}

image.gif

这里的topic为对第一条中的订阅的topic.同时还有一个message信息,这个message即为使用ChaCha20Poly1305加密的数据。

3.3 获取sym_key

       根据对称加密,用户钱包一定会获得一个密钥,这个密钥其实就是用户扫描的二维码数据内,我们使用除wallet外的其他任何应用的扫码功能去扫描点击连接后显示的二维码,得到wc协议数据,这里获取到的内容如下:

wc:ae450e4f4aa30817eee55d89d28e7ac63765a48c50dc4f84d5ad4512f8b1224c@2
?expiryTimestamp=1721392578&
relay-protocol=irn&
symKey=29630042945a25194e1500a42e9c62e10fa33cf5c462e71f17a317478a577f66

image.gif

wc协议的格式如下:

wc:{topic}@2?expiryTimestamp={}&relay-protocol=irn&symKey={}

image.gif

由此可知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=

image.gif

symKey为:

29630042945a25194e1500a42e9c62e10fa33cf5c462e71f17a317478a577f66

image.gif

根据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

image.gif

序列化消息格式为:

即将数据转换为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}")

image.gif

这样我们可以得到解密数据:

{
    "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"
    }
}

image.gif

我们使用二维码内的sym_key获取了websocket发送加密数据信息,这就证明wallectconnect确实如上面所说使用对称加密方式和用户钱包进行通信。

感谢关注,感谢点赞 !!

image.gif 编辑

目录
相关文章
|
弹性计算 安全 Linux
使用阿里云ECS服务器和frp配置SSH反向代理
校园网、公司内网中的设备一般是没有公网ip的,所以没办法用SSH直接连接。但是平时VSCode远程连接调调代码啥的都是通过SSH来连接的,平时不在学校或者公司的时候会很麻烦。虽然说VPN、向日葵花生壳之类的方法都能解决这个问题,但是这些方法不是麻烦就是贵或者不安全。frp只需要一台有公网ip的服务器就能实现外网SSH访问,相对来说比较简单。
|
机器学习/深度学习 算法 数据挖掘
交叉验证之KFold和StratifiedKFold的使用(附案例实战)
交叉验证之KFold和StratifiedKFold的使用(附案例实战)
3719 0
|
7月前
|
数据采集 人工智能 安全
从入门到精通:手把手教你用LLaMA Factory微调专属大模型
大家好,我是AI博主maoku老师。你是否觉得大模型“懂王”式回答不够专业?微调正是破局关键!本文带你深入浅出理解微调原理,掌握LoRA、量化、对话模板三大核心技术,并手把手教你用LLaMA Factory零代码实践,四步打造专属Web安全专家模型。从数据准备到部署应用,全程实战,助你将大模型从“通才”炼成“专才”,实现个性化、低成本、高效率的AI赋能。
|
存储 JavaScript 区块链
小试牛刀-walletconnect二维码及交互
最近在使用walletconnect协议和typescript语言实现相关交互功能,在此对从walletconnet协议二维码生成、连接后发送交易事务、签名事务、签名任意信息的处理进行记录,加深对walletconnect的理解,熟悉对其组件的使用,同时希望帮助到有实现相关功能的朋友。
498 1
|
5月前
|
数据采集 人工智能 自然语言处理
OpenClaw阿里云/本地部署与Apify MCP无缝集成,全网结构化数据抓取采集增强指南
AI编程工具的联网数据采集能力,往往卡在“JS渲染页面抓不到、反爬机制绕不开、数据格式不规范”三大痛点上。OpenClaw作为灵活的AI Agent平台,2026年通过与Apify生态深度集成,完美解决了这些问题——借助Apify的Agent Skills与MCP Server,OpenClaw不仅能突破JS渲染与反爬限制,还能直接输出结构化表格数据,让数据采集从“文本摘要”升级为“即用型数据集”。
2141 14
|
安全 Shell 网络安全
Charles - 夜神模拟器证书安装App抓包
Charles - 夜神模拟器证书安装App抓包 前言 一、软件安装 1.Openssl安装 1.1下载安装 1.2配置环境变量 1.3查看openssl版本,输入命令:openssl version 2.夜神模拟器安装 1.1 下载安装 1.2工具准备,MT管理器 3.Charles安装 二、Charles 安装证书,抓包 1.Charles破解 2.安装证书并导出 3.开启代理模式 4.证书格式化 5.通过MT管理器将证书配置到模拟器中 6.模拟器WiFi填入Charles代理的IP和端口 7.抓包示例
2403 0
Charles - 夜神模拟器证书安装App抓包
|
监控 负载均衡 API
Apache Apisix轻松打造亿级流量Api网关
Apache APISIX 是一个动态、实时、高性能的 API 网关,提供负载均衡、动态上行、灰度发布、熔断、鉴权、可观测等丰富的流量管理功能。适用于处理传统南北向流量、服务间东西向流量及 k8s 入口控制。Airflow 是一个可编程、调度和监控的工作流平台,基于有向无环图 (DAG) 定义和执行任务,提供丰富的命令行工具和 Web 管理界面,方便系统运维和管理。
Apache Apisix轻松打造亿级流量Api网关
|
存储 人工智能 自然语言处理
VLMs多模态大模型当下进展与思考(2)
VLMs多模态大模型当下进展与思考
1093 10
|
缓存 网络协议 开发者
计算机网络学习笔记(三)
TCP的异常终止使用reset报文,用于强制关闭连接,不等待正常四次挥手。RST标志位设置时,发送方直接丢弃缓存,接收方无需确认。常见情况包括:尝试连接服务器未开放的端口、一方异常崩溃、收到不属于现有连接的报文、超时未收到确认报文或应用开发者优化效率。reset报文帮助释放资源,防止连接挂起。
582 0
|
移动开发 算法
秒懂算法 | A*搜索
本篇内容包括了A*搜索算法的原理精解以及2个例题。
1628 1
秒懂算法 | A*搜索