微信项目实现简介
一、 它是完全自包含的项目吗?
在代码依赖和二进制层面,是的;在系统交互层面,它是轻量自包含。
-
代码与构建层面:100% 自包含(零第三方依赖)
- 查看项目的
go.mod可以发现,里面只有一行go 1.24,没有任何require,仓库中甚至没有go.sum文件。 - 它完全基于 Go 官方标准库(
net/http、mime/multipart、encoding/json、crypto、os等)编写。 - 编译出来的直接是一个静态二进制文件(
pushd),扔到任何 Linux 服务器上就可以直接跑,不需要装 Python/Node 运行时,也不需要起 Redis、RabbitMQ 等任何中间件。 - 附带的客户端
client/send.py同样只用了 Python 原生库(urllib.request、json、argparse),也是零依赖。
- 查看项目的
-
外部环境依赖(边界说明)
- 主通道(企业微信):仅需服务器能正常访问公网域名
qyapi.weixin.qq.com。 - 媒体兜底通道(个人微信 weclaw):依赖宿主机系统的
ssh命令以及远端机器上的weclaw程序(如果没配,服务会自动禁用兜底,主流程不受影响)。
- 主通道(企业微信):仅需服务器能正常访问公网域名
二、 微信交互部分用了什么库?加解密是怎么处理的?
这里有一个非常关键的技术常识区分:这个项目没有使用任何微信 SDK,也没有写任何加解密逻辑(WXBizMsgCrypt)。
1. 用了什么库?
“零库纯手写”。没有引入任何微信第三方开发包(如 silenceper/wechat、easywechat 等),全部直接用 Go 标准库拼装 HTTP 请求:
- 换取 Token:
net/http.Client发起GET https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=...&corpsecret=... - 上传素材:标准库
mime/multipart.NewWriter拼装表单流,向media/upload发起POST。 - 发送消息:标准库
json.Marshal序列化消息体,向message/send?access_token=...发起POST。
2. 为什么没有“加密解密”?
在微信开发体系中,只有“接收用户消息/事件回调”(Inbound Webhook)才需要加解密(即企业微信强制要求的 AES-256-CBC、PKCS#7 Padding、SHA1 验签等)。
而 pushd 是一个纯单向的主动推送服务(Outbound Push):
- 官方的主动发送接口(
cgi-bin/message/send)走的是标准 HTTPS 传输加密,应用层传输的是纯 JSON 明文。 - 它的安全凭证完全基于 Access Token 机制(Corpid + CorpSecret 换取的 2 小时临时令牌),因此根本不需要复杂的报文加解密。
3. 项目里真正存在的“密码学/安全”代码在哪里?
虽然没有微信报文加解密,但为了保证推送网关本身的安全,作者在以下两个地方运用了密码学与安全防护:
- 防时序侧信道攻击的鉴权比对(
server.go):
服务端校验客户端 Bearer Token 时,为了防止黑客通过接口响应耗时微秒级的差异推断出 Token 长度或字符,代码使用 SHA-256 固定哈希后再用底层常量时间比对:func constantTimeEq(a, b string) bool { ha := sha256.Sum256([]byte(a)) hb := sha256.Sum256([]byte(b)) return subtle.ConstantTimeCompare(ha[:], hb[:]) == 1 } - 底层 SSRF 与 DNS Rebinding 拦截(
media.go):
在 URL 摄入媒体时,通过重写http.Transport.DialContext,在建立 TCP 握手的瞬时提取对端真实 IP 判定是否为私网地址(127.0.0.1、10.x、192.168.x、169.254.x),杜绝服务被利用攻击内网。