diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb index 7eafbb571f841562f76397c036d648cdf2c7f599..0f0e931c06cfdb3594e8bbf6d464403841753e1f 100644 --- a/activesupport/lib/active_support/key_generator.rb +++ b/activesupport/lib/active_support/key_generator.rb @@ -15,8 +15,9 @@ def initialize(secret, options = {}) end # Returns a derived key suitable for use. The default key_size is chosen - # to be compatible with the acceptable key length of aes-256-cbc, the default cipher. - def generate_key(salt, key_size=32) + # to be compatible with the default settings of ActiveSupport::MessageVerifier. + # i.e. OpenSSL::Digest::SHA1#block_length + def generate_key(salt, key_size=64) OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size) end end @@ -30,10 +31,9 @@ def initialize(key_generator) @cache_keys = Concurrent::Map.new end - # Returns a derived key suitable for use. The default key_size is chosen - # to be compatible with the acceptable key length of aes-256-cbc, the default cipher. - def generate_key(salt, key_size=32) - @cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size) + # Returns a derived key suitable for use. + def generate_key(*args) + @cache_keys[args.join] ||= @key_generator.generate_key(*args) end end diff --git a/activesupport/test/key_generator_test.rb b/activesupport/test/key_generator_test.rb index 6cf72f1fecf7fac78c17048e3d652ec60378a837..b60077460e0a4b3849611f216e0fb1e8dee2a809 100644 --- a/activesupport/test/key_generator_test.rb +++ b/activesupport/test/key_generator_test.rb @@ -19,7 +19,7 @@ def setup test "Generating a key of the default length" do derived_key = @generator.generate_key("some_salt") assert_kind_of String, derived_key - assert_equal OpenSSL::Cipher.new('aes-256-cbc').key_len, derived_key.length, "Should have generated a key of the default size" + assert_equal 64, derived_key.length, "Should have generated a key of the default size" end test "Generating a key of an alternative length" do @@ -27,6 +27,21 @@ def setup assert_kind_of String, derived_key assert_equal 32, derived_key.length, "Should have generated a key of the right size" end + + test "Expected results" do + # For any given set of inputs, this method must continue to return + # the same output: if it changes, any existing values relying on a + # key would break. + + expected = "b129376f68f1ecae788d7433310249d65ceec090ecacd4c872a3a9e9ec78e055739be5cc6956345d5ae38e7e1daa66f1de587dc8da2bf9e8b965af4b3918a122" + assert_equal expected, ActiveSupport::KeyGenerator.new("0" * 64).generate_key("some_salt").unpack('H*').first + + expected = "b129376f68f1ecae788d7433310249d65ceec090ecacd4c872a3a9e9ec78e055" + assert_equal expected, ActiveSupport::KeyGenerator.new("0" * 64).generate_key("some_salt", 32).unpack('H*').first + + expected = "cbea7f7f47df705967dc508f4e446fd99e7797b1d70011c6899cd39bbe62907b8508337d678505a7dc8184e037f1003ba3d19fc5d829454668e91d2518692eae" + assert_equal expected, ActiveSupport::KeyGenerator.new("0" * 64, iterations: 2).generate_key("some_salt").unpack('H*').first + end end class CachingKeyGeneratorTest < ActiveSupport::TestCase