aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--guides/source/active_record_querying.md2
-rw-r--r--guides/source/upgrading_ruby_on_rails.md2
-rw-r--r--railties/CHANGELOG.md16
-rw-r--r--railties/lib/rails/commands/secrets/secrets_command.rb2
-rw-r--r--railties/lib/rails/secrets.rb21
-rw-r--r--railties/test/secrets_test.rb4
6 files changed, 29 insertions, 18 deletions
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index 31220f9be2..38a9d61f4b 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -1871,7 +1871,7 @@ Which will execute:
```sql
SELECT count(DISTINCT clients.id) AS count_all FROM clients
- LEFT OUTER JOIN orders ON orders.client_id = client.id WHERE
+ LEFT OUTER JOIN orders ON orders.client_id = clients.id WHERE
(clients.first_name = 'Ryan' AND orders.status = 'received')
```
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 6005298127..3afc0e5309 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -80,7 +80,7 @@ It is only soft-deprecated, which means that your code will not break at the
moment and no deprecation warning will be displayed but this constant will be
removed in the future.
-Also, if you have pretty old YAML documents containg dumps of such objects,
+Also, if you have pretty old YAML documents containing dumps of such objects,
you may need to load and dump them again to make sure that they reference
the right constant and that loading them won't break in the future.
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 54bf0ec65e..327b6ab66d 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,3 +1,19 @@
+* Improve encryption for encrypted secrets.
+
+ Switch to aes-128-gcm authenticated encryption. Also generate a random
+ initialization vector for each encryption so the same input and key can
+ generate different encrypted data.
+
+ Double the encryption key entropy by properly extracting the underlying
+ bytes from the hexadecimal seed key.
+
+ NOTE: Since the encryption mechanism has been switched, you need to run
+ this script to upgrade:
+
+ https://gist.github.com/kaspth/bc37989c2f39a5642112f28b1d93f343
+
+ *Stephen Touset*
+
## Rails 5.1.0.beta1 (February 23, 2017) ##
* Add encrypted secrets in `config/secrets.yml.enc`.
diff --git a/railties/lib/rails/commands/secrets/secrets_command.rb b/railties/lib/rails/commands/secrets/secrets_command.rb
index 65db81ac73..b9ae5d8b3b 100644
--- a/railties/lib/rails/commands/secrets/secrets_command.rb
+++ b/railties/lib/rails/commands/secrets/secrets_command.rb
@@ -18,7 +18,7 @@ module Rails
end
def edit
- if ENV["EDITOR"].empty?
+ if ENV["EDITOR"].to_s.empty?
say "No $EDITOR to open decrypted secrets in. Assign one like this:"
say ""
say %(EDITOR="mate --wait" bin/rails secrets:edit)
diff --git a/railties/lib/rails/secrets.rb b/railties/lib/rails/secrets.rb
index a083914109..2a95712cd9 100644
--- a/railties/lib/rails/secrets.rb
+++ b/railties/lib/rails/secrets.rb
@@ -1,4 +1,5 @@
require "yaml"
+require "active_support/message_encryptor"
module Rails
# Greatly inspired by Ara T. Howard's magnificent sekrets gem. 😘
@@ -12,6 +13,7 @@ module Rails
end
end
+ @cipher = "aes-128-gcm"
@read_encrypted_secrets = false
@root = File # Wonky, but ensures `join` uses the current directory.
@@ -30,20 +32,19 @@ module Rails
end
def generate_key
- cipher = new_cipher
- SecureRandom.hex(cipher.key_len)[0, cipher.key_len]
+ SecureRandom.hex(OpenSSL::Cipher.new(@cipher).key_len)
end
def key
ENV["RAILS_MASTER_KEY"] || read_key_file || handle_missing_key
end
- def encrypt(text)
- cipher(:encrypt, text)
+ def encrypt(data)
+ encryptor.encrypt_and_sign(data)
end
def decrypt(data)
- cipher(:decrypt, data)
+ encryptor.decrypt_and_verify(data)
end
def read
@@ -97,14 +98,8 @@ module Rails
end
end
- def new_cipher
- OpenSSL::Cipher.new("aes-256-cbc")
- end
-
- def cipher(mode, data)
- cipher = new_cipher.public_send(mode)
- cipher.key = key
- cipher.update(data) << cipher.final
+ def encryptor
+ @encryptor ||= ActiveSupport::MessageEncryptor.new([ key ].pack("H*"), cipher: @cipher)
end
end
end
diff --git a/railties/test/secrets_test.rb b/railties/test/secrets_test.rb
index 36e42cf1f9..953408f0b4 100644
--- a/railties/test/secrets_test.rb
+++ b/railties/test/secrets_test.rb
@@ -54,9 +54,9 @@ class Rails::SecretsTest < ActiveSupport::TestCase
test "reading from key file" do
run_secrets_generator do
- File.binwrite("config/secrets.yml.key", "How do I know you feel it?")
+ File.binwrite("config/secrets.yml.key", "00112233445566778899aabbccddeeff")
- assert_equal "How do I know you feel it?", Rails::Secrets.key
+ assert_equal "00112233445566778899aabbccddeeff", Rails::Secrets.key
end
end