ActivityPub与Mastodon:获取Actor的签名验证循环困境求解
解决ActivityPub与Mastodon互操作时的Actor获取签名循环问题
问题根源
你遇到的401错误是因为目标Mastodon实例启用了严格的请求验证——这属于Mastodon对ActivityPub标准的扩展,虽然标准中获取公共Actor资源不需要签名,但部分实例会要求所有请求(包括GET)都带签名,以此防范未授权的批量抓取或恶意访问。而所谓的“鸡生蛋”困境,核心是双方验证签名时都需要对方的Actor公钥,但获取公钥又依赖请求的合法性。
循环困境的解决方案
优先尝试未签名请求
绝大多数公开的Mastodon实例允许未签名GET请求获取公共Actor,你测试的awoo.space只是少数启用严格验证的特例。先直接发送未签名请求,若成功则直接获取Actor数据;若返回401,再走签名流程。签名请求的正确逻辑
当必须发送签名GET请求时,核心前提是你的Actor必须是公开可访问的:- 生成签名时,在
Signature请求头中指定keyId为你的Actor完整URL(比如https://你的实例域名/users/你的账号)。 - 目标实例收到请求后,会主动通过
keyId拉取你的Actor(这个请求由对方发起,不需要你签名),拿到你的公钥后验证签名合法性,验证通过后就会返回目标Actor数据。 - 这里的关键是:对方验证你的签名时,是主动去获取你的公钥,不需要你提前传递,只要你的Actor能被公开访问即可打破循环。
- 生成签名时,在
Mastodon自身的处理逻辑
Mastodon在获取远程Actor时,遵循一套成熟的流程来避免循环:
- 首先发送未签名的GET请求,若返回200则直接解析Actor数据;
- 若收到401或403,再使用本地实例的Actor私钥生成签名请求,签名头中明确
keyId指向本地Actor URL; - 远程实例验证签名时,会先拉取Mastodon实例的Actor公钥,验证通过后返回目标Actor;
- 同时,Mastodon会缓存获取到的远程Actor公钥,避免重复请求,提升交互效率。
针对你的测试请求
如果要给curl请求添加签名,需要生成符合HTTP Signatures标准的Signature头,大致格式如下(需替换成你的Actor信息和私钥签名结果):
curl -H 'Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"' \ -H 'Signature: keyId="https://你的实例域名/users/你的账号",algorithm="rsa-sha256",headers="(request-target) host date digest",signature="你的签名内容"' \ https://awoo.space/users/DPA
注:生成签名需要对请求的(request-target)、host、date、digest等字段进行加密签名,具体实现需参照HTTP Signatures规范。
内容的提问来源于stack exchange,提问作者Daniel Abrecht
相关产品推荐
相关产品推荐

