Module: Rack::Protection::Encryptor

Defined in:
lib/rack/protection/encryptor.rb

Constant Summary collapse

CIPHER =
'aes-256-gcm'
DELIMITER =
'--'

Class Method Summary collapse

Class Method Details

.base64_decode(str) ⇒ Object



15
16
17
# File 'lib/rack/protection/encryptor.rb', line 15

def self.base64_decode(str)
  str.unpack1('m0')
end

.base64_encode(str) ⇒ Object



11
12
13
# File 'lib/rack/protection/encryptor.rb', line 11

def self.base64_encode(str)
  [str].pack('m0')
end

.decrypt_message(data, secret) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rack/protection/encryptor.rb', line 38

def self.decrypt_message(data, secret)
  return unless data

  cipher = OpenSSL::Cipher.new(CIPHER)
  cipher_text, iv, auth_tag = data.split(DELIMITER, 3).map! { |v| base64_decode(v) }

  # This check is from ActiveSupport::MessageEncryptor
  # see: https://github.com/ruby/openssl/issues/63
  return if auth_tag.nil? || auth_tag.bytes.length != 16

  cipher.decrypt
  cipher.key = secret[0, cipher.key_len]
  cipher.iv  = iv
  cipher.auth_tag = auth_tag
  cipher.auth_data = ''

  decrypted_data = cipher.update(cipher_text)
  decrypted_data << cipher.final
  decrypted_data
rescue OpenSSL::Cipher::CipherError, TypeError, ArgumentError
  nil
end

.encrypt_message(data, secret, auth_data = '') ⇒ Object

Raises:

  • (ArgumentError)


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/rack/protection/encryptor.rb', line 19

def self.encrypt_message(data, secret, auth_data = '')
  raise ArgumentError, 'data cannot be nil' if data.nil?

  cipher = OpenSSL::Cipher.new(CIPHER)
  cipher.encrypt
  cipher.key = secret[0, cipher.key_len]

  # Rely on OpenSSL for the initialization vector
  iv = cipher.random_iv

  # This must be set to properly use AES GCM for the OpenSSL module
  cipher.auth_data = auth_data

  cipher_text = cipher.update(data)
  cipher_text << cipher.final

  "#{base64_encode cipher_text}#{DELIMITER}#{base64_encode iv}#{DELIMITER}#{base64_encode cipher.auth_tag}"
end