【问题标题】:ActiveSupport::MessageEncryptor different between rails 3.1 and 3.2Rails 3.1 和 3.2 之间的 ActiveSupport::MessageEncryptor 不同
【发布时间】:2015-02-04 06:33:26
【问题描述】:

我有一个旧项目,我正试图从 Rails 3.1 升级到 3.2。我遇到了 ActiveSupport::MessageEncryptor 的问题 - 在 Rails 3.1 中加密的数据无法在 Rails 3.2 中解密 - 我收到以下错误: ActiveSupport::MessageEncryptor::InvalidMessage

这是 Rails 控制台中两个会话的输出 - 首先我在 Rails 3.1.12 中加密了一个示例字符串:

Loading development environment (Rails 3.1.12)
2.1.5 :001 > secret = "01ac28236532ee53e0a0c4f562ce2f398c7e9287f5015d2baab0e1d986579a1a2fb6296946327ffffc3a"
 => "01ac28236532ee53e0a0c4f562ce2f398c7e9287f5015d2baab0e1d986579a1a2fb6296946327ffffc3a"
2.1.5 :002 > encryptor =  ActiveSupport::MessageEncryptor.new(secret)
 => #<ActiveSupport::MessageEncryptor:0x007fd8a6f607a8 @secret="01ac28236532ee53e0a0c4f562ce2f398c7e9287f5015d2baab0e1d986579a1a2fb6296946327ffffc3a", @cipher="aes-256-cbc">
2.1.5 :003 > encryptor.encrypt_and_sign("123-45-6789")
 => "BAhJIktNaE1kZHkwUHZZWVFub2RVeFk3MEY2Sm9LMjA3SzUzYXYxVStVb25HZlhjPS0tTzRXZmRwODJqZ1Boa0twdHlWeWthUT09BjoGRUY=--70b6be792b274777104f53c2f4f324320e9cd808"

现在我尝试在 Rails 3.2 环境中解密生成的字符串:

Loading development environment (Rails 3.2.21)
2.1.5 :001 > secret = "01ac28236532ee53e0a0c4f562ce2f398c7e9287f5015d2baab0e1d986579a1a2fb6296946327ffffc3a"
 => "01ac28236532ee53e0a0c4f562ce2f398c7e9287f5015d2baab0e1d986579a1a2fb6296946327ffffc3a"
2.1.5 :002 > encryptor =  ActiveSupport::MessageEncryptor.new(secret)
 => #<ActiveSupport::MessageEncryptor:0x007f8802a02508 @secret="01ac28236532ee53e0a0c4f562ce2f398c7e9287f5015d2baab0e1d986579a1a2fb6296946327ffffc3a", @cipher="aes-256-cbc", @verifier=#<ActiveSupport::MessageVerifier:0x007f8802a09bf0 @secret="01ac28236532ee53e0a0c4f562ce2f398c7e9287f5015d2baab0e1d986579a1a2fb6296946327ffffc3a", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer>, @serializer=Marshal>
2.1.5 :003 > encryptor.decrypt_and_verify("BAhJIktNaE1kZHkwUHZZWVFub2RVeFk3MEY2Sm9LMjA3SzUzYXYxVStVb25HZlhjPS0tTzRXZmRwODJqZ1Boa0twdHlWeWthUT09BjoGRUY=--70b6be792b274777104f53c2f4f324320e9cd808")
ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage

在这两种情况下,我都使用默认密码“aes-256-cbc”;我确实注意到 rails 3.2 中的 ActiveSupport::MessageEncryptor 对象附加了一些实例变量。我希望能够以可以在 rails 3.2 下读取的格式在新数据库字段中重写我的数据,因此我希望 ActiveSupport::MessageEncryptor 在 3.1 中具有它在 3.2 中的所有属性.知道我错过了什么吗?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 encryption ruby-on-rails-3.2


    【解决方案1】:

    我发现了我的问题:

    MessageEncryptor 对象在 Rails 3.2 中具有但在 3.1 中没有的属性之一是 MessageVerifier。 (在 3.1 中,函数 verifier 包装了对 MessageVerifier.new 的调用,而在 3.2 中,验证器是实例变量 @verifier 的读取器,在初始化时创建。)

    在 3.1 中,MessageVerifier 使用 Marshal 作为其序列化程序。在 3.2 中,它支持选择另一个序列化器。 MessageEncryptor 的初始化程序调用 MessageVerifier.new 但为序列化程序指定 NullSerializer。

    因此,虽然我的旧数据已被验证器使用 Marshal 作为其序列化器的加密器加密,但新加密器正尝试使用序列化器为 NullSerializer 的验证器读取它。

    关于这一切的最令人困惑的是,我找不到任何关于同一问题的帖子。这怎么可能对任何人有用?

    无论如何,我使用 ActiveSupport::MessageEncryptor 上的猴子补丁解决了我的问题,如下所示:

    module ActiveSupport
      class MessageEncryptor
        def initialize(secret, options = {})
    
          unless options.is_a?(Hash)
            ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :cipher => 'algorithm' to specify the cipher algorithm."
            options = { :cipher => options }
          end
    
          @secret = secret
          @cipher = options[:cipher] || 'aes-256-cbc'
    
          # the default version of this function creates the verifier with NullSerializer, not providing the option to specify a serializer
          # however, in ActiveSupport 3.1 and earlier MessageVerifier uses the Marshal serializer; thus, all our existing data was verified
          # and subsequently encrypted using Marshal.
          # Considering migrating all existing data over to a new value using NullSerializer, as the latest version of ActiveSupport::MessageEncryptor
          # still has a verifier that's hard-coded to use NullSerializer. If we do that, then we can get rid of this patch once the migration is complete
          @verifier = MessageVerifier.new(@secret, :serializer => options[:verifier_serializer] || NullSerializer)
          @serializer = options[:serializer] || Marshal
    
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 2023-01-24
      相关资源
      最近更新 更多