Skip to content

Instantly share code, notes, and snippets.

@EugZol
Last active August 30, 2021 19:03
Show Gist options
  • Save EugZol/435ee06ec08b25a71bd8799a530c6322 to your computer and use it in GitHub Desktop.
Save EugZol/435ee06ec08b25a71bd8799a530c6322 to your computer and use it in GitHub Desktop.
# Usage:
# ruby credentials_decryptor.rb production.yml.enc production.key
require 'openssl'
require 'base64'
# References:
# - https://github.com/rails/rails/blob/main/activesupport/lib/active_support/encrypted_file.rb
# - https://github.com/rails/rails/blob/b71a9ccce04ac08e159d4a21de91a8d76f13d8d0/activesupport/lib/active_support/message_encryptor.rb#L147
class Credentials
def self.decrypt(data_bin, key_hex)
encrypted_data, iv, auth_tag = data_bin.split("--").map { |v| ::Base64.strict_decode64(v) }
key = [key_hex].pack('H*')
cipher_type =
case key.bytes.length
when 16
'aes-128-gcm'
when 32
'aes-256-gcm'
else
raise "Wrong key length: #{key.bytes.length}"
end
raise "Unauthenticated message" if auth_tag.nil? || auth_tag.bytes.length != 16
cipher = OpenSSL::Cipher.new(cipher_type)
cipher.decrypt
cipher.key = key
cipher.iv = iv
cipher.auth_tag = auth_tag
cipher.auth_data = ""
decrypted_data = cipher.update(encrypted_data)
decrypted_data << cipher.final
if decrypted_data.bytes[0..1] == [4, 8]
Marshal.load(decrypted_data)
else
decrypted_data
end
end
def self.encrypt(data_bin, key_hex)
# TODO
end
end
if __FILE__ == $0
data_bin = File.binread(ARGV[0])
key_hex = File.binread(ARGV[1])
puts Credentials.decrypt(data_bin, key_hex)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment