跨应用解密ActiveSupport::MessageEncryptor值报InvalidMessage错误如何解决?
问题解决方案
- 加密初始化参数强制对齐
不同版本的ActiveSupport默认配置差异极大,是触发ActiveSupport::MessageEncryptor::InvalidMessage报错的最常见原因。禁止依赖框架默认值,需要在Rails应用和独立脚本两端初始化ActiveSupport::MessageEncryptor时显式指定所有配置参数:
# 两端的crypt方法统一使用如下配置,参数值和Rails侧实际生效的配置保持一致 def crypt ActiveSupport::MessageEncryptor.new( KEY, cipher: "aes-256-gcm", # Rails 5.2+默认算法,旧版本替换为"aes-256-cbc" serializer: Marshal, # 如果Rails侧配置为JSON序列化则修改为JSON digest: "SHA256" # Rails旧版本默认值为SHA1,按需对齐 ) end
- 密钥长度合规处理
加密算法对密钥长度有明确要求,比如aes-256需要32字节长度的密钥,直接传入任意长度的原始字符串会导致加密逻辑不兼容。Rails原生会对原始密钥做哈希派生得到符合长度的密钥,两端需要统一派生逻辑:
# 先派生出符合长度要求的密钥再传入 def crypt # 第二个参数32对应aes-256算法的密钥长度,使用aes-128则改为16 derived_key = ActiveSupport::KeyGenerator.new(KEY).generate_key("Rails侧使用的salt值", 32) ActiveSupport::MessageEncryptor.new(derived_key, cipher: "aes-256-gcm") end
- Base64编解码逻辑对齐
你当前生成令牌时指定了padding: false生成无填充的Base64内容,需要确认Rails侧解码时使用的Base64.urlsafe_decode64逻辑和脚本端一致,没有额外的填充补全或字符过滤逻辑。 - payload序列化规则对齐
如果payload包含符号、时间对象等非JSON兼容的Ruby类型,两端必须使用相同的序列化器,一端用Marshal一端用JSON会直接触发解密失败。
内容的提问来源于stack exchange,提问作者WagnerMatosUK
相关产品推荐
相关产品推荐

