Class: Rack::Bacoo::Encryptor
- Inherits:
-
Object
- Object
- Rack::Bacoo::Encryptor
- Defined in:
- lib/rack/bacoo/encryptor.rb
Constant Summary collapse
- DecryptionError =
Class.new(StandardError)
- AUTH_TAG_LENGTH =
16- CIPHER =
"aes-256-gcm"- SALT =
"entropy comes from the password"- SEPARATOR =
"--"
Instance Method Summary collapse
- #decrypt(encrypted_message) ⇒ Object
- #encrypt(data) ⇒ Object
-
#initialize(password) ⇒ Encryptor
constructor
A new instance of Encryptor.
Constructor Details
#initialize(password) ⇒ Encryptor
Returns a new instance of Encryptor.
16 17 18 19 20 21 |
# File 'lib/rack/bacoo/encryptor.rb', line 16 def initialize(password) key_len = new_cipher.key_len digest = OpenSSL::Digest.new("SHA256") # Rationale on how the key is generated: https://github.com/rails/rails/pull/6952 @key = OpenSSL::PKCS5.pbkdf2_hmac(password, SALT, 1000, key_len, digest) end |
Instance Method Details
#decrypt(encrypted_message) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/rack/bacoo/encryptor.rb', line 34 def decrypt() cipher = new_cipher encrypted_data, iv, auth_tag = extract_parts() # Currently the OpenSSL bindings do not raise an error if auth_tag is # truncated, which would allow an attacker to easily forge it: # https://github.com/ruby/openssl/issues/63 raise DecryptionError, "truncated auth_tag" if auth_tag.bytesize != AUTH_TAG_LENGTH cipher.decrypt cipher.key = @key cipher.iv = iv cipher.auth_tag = auth_tag cipher.auth_data = "" cipher.update(encrypted_data) + cipher.final end |
#encrypt(data) ⇒ Object
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/rack/bacoo/encryptor.rb', line 23 def encrypt(data) cipher = new_cipher cipher.encrypt cipher.key = @key iv = cipher.random_iv cipher.auth_data = "" encrypted_data = cipher.update(data) + cipher.final parts = [encrypted_data, iv, cipher.auth_tag(AUTH_TAG_LENGTH)] parts.map { ::Base64.strict_encode64(_1) }.join(SEPARATOR) end |