Signal Protocol解密PreKeyWhisperMessage因Signed PreKey ID解析异常报错的问题排查求助
大家好,我最近在基于Signal Protocol实现消息加密解密时,碰到了一个卡在Protobuf编解码环节的棘手问题,解密时始终抛出[Error: Missing Signed PreKey for PreKeyWhisperMessage]错误,已经自行追踪排查了好一阵,想请各位帮忙分析下问题根源。
问题核心现象
发送端加密后的二进制数据,接收端完整接收后(我对比过发送和接收的Uint8数组,内容完全一致),通过库的PreKeyWhisperMessage.decode方法解析后,signedPreKeyId字段的值和发送端编码前的原始值完全不符,这直接导致接收端找不到对应的Signed PreKey,最终解密失败。
发送端加密流程细节
我用以下代码完成消息加密:
const senderSessionCipher = await getOrCreateSessionCipher(senderStore, recipientAddress, recipientIdentifier); const ciphertext = await senderSessionCipher.encrypt(messageBuffer);
跟踪SessionCipher的encrypt方法源码,内部最终会调用Protobuf的编码逻辑生成二进制密文:
const encodedPreKeyMsg = libsignal_protocol_protobuf_ts_1.PreKeyWhisperMessage.encode(preKeyMsg).finish();
编码前我打印了preKeyMsg,其中signedPreKeyId的值是1737701424087465——这个ID是我通过自定义函数生成的:
function makeID() { const timestamp = Date.now() const random = Math.floor(Math.random() * 1000) return parseInt(`${timestamp}${random}`, 10) }
编码后的encodedPreKeyMsg是正常的Uint8数组,且传输到接收端的过程中数据没有损坏。
接收端解密流程细节
接收端识别到消息类型为3,执行以下解密代码:
const cipher = new SessionCipher(store, sender_address) const plaintextBytes = await cipher.decryptPreKeyWhisperMessage(message.body!, 'binary')
跟踪decryptPreKeyWhisperMessage的源码,内部会调用Protobuf的解码逻辑解析二进制数据:
const preKeyProto = libsignal_protocol_protobuf_ts_1.PreKeyWhisperMessage.decode(messageData);
我确认了接收端的messageData和发送端的encodedPreKeyMsg完全一致,但解码后的preKeyProto里,signedPreKeyId居然变成了605798825,和发送端的原始值完全不匹配!
我的几个疑问
- 会不会是我生成的
signedPreKeyId长度超标了?这个ID是16位左右的数字,会不会超出了Signal Protocol定义的Protobuf结构中signedPreKeyId的类型范围(比如该字段仅支持32位整数,而我生成的是64位?) - 有没有可能是我使用的Protobuf库不对?如果是库的问题,能不能给我一个正确的yarn安装命令?
备注:内容来源于stack exchange,提问作者Adekojo Emmanuel

