Class: Strongbox::Lock
- Inherits:
-
Object
- Object
- Strongbox::Lock
- Defined in:
- lib/strongbox/lock.rb
Overview
The Lock class encrypts and decrypts the protected attribute. It automatically encrypts the data when set and decrypts it when the private key password is provided.
Instance Method Summary collapse
-
#blank? ⇒ Boolean
Needed for validations.
- #content(plaintext) ⇒ Object
-
#decrypt(password = nil, ciphertext = nil) ⇒ Object
Given the private key password decrypts the attribute.
- #encrypt(plaintext) ⇒ Object
- #encrypt! ⇒ Object
- #ensure_required_columns ⇒ Object
-
#initialize(name, instance, options = {}) ⇒ Lock
constructor
A new instance of Lock.
- #length ⇒ Object
- #nil? ⇒ Boolean
- #size ⇒ Object
- #to_json(options = nil) ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(name, instance, options = {}) ⇒ Lock
Returns a new instance of Lock.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/strongbox/lock.rb', line 7 def initialize name, instance, = {} @name = name @instance = instance @size = 0 = Strongbox..merge() @base64 = [:base64] @public_key = [:public_key] || [:key_pair] @private_key = [:private_key] || [:key_pair] @padding = [:padding] @symmetric = [:symmetric] @symmetric_cipher = [:symmetric_cipher] @symmetric_key = [:symmetric_key] || "#{name}_key" @symmetric_iv = [:symmetric_iv] || "#{name}_iv" @ensure_required_columns = [:ensure_required_columns] @deferred_encryption = [:deferred_encryption] end |
Instance Method Details
#blank? ⇒ Boolean
Needed for validations
126 127 128 |
# File 'lib/strongbox/lock.rb', line 126 def blank? @raw_content.blank? && @instance[@name].blank? end |
#content(plaintext) ⇒ Object
27 28 29 30 31 32 33 34 |
# File 'lib/strongbox/lock.rb', line 27 def content plaintext @size = plaintext.size unless plaintext.nil? # For validations if @deferred_encryption @raw_content = plaintext else encrypt plaintext end end |
#decrypt(password = nil, ciphertext = nil) ⇒ Object
Given the private key password decrypts the attribute. Will raise OpenSSL::PKey::RSAError if the password is wrong.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/strongbox/lock.rb', line 77 def decrypt password = nil, ciphertext = nil return @raw_content if @deferred_encryption && @raw_content # Given a private key and a nil password OpenSSL::PKey::RSA.new() will # *prompt* for a password, we default to an empty string to avoid that. ciphertext ||= @instance[@name] unless @deferred_encryption return nil if ciphertext.nil? return "" if ciphertext.empty? end return "*encrypted*" if password.nil? unless @private_key raise StrongboxError.new("#{@instance.class} model does not have private key_file") end if ciphertext ciphertext = Base64.decode64(ciphertext) if @base64 private_key = get_rsa_key(@private_key,password) if @symmetric == :always random_key = @instance[@symmetric_key] random_iv = @instance[@symmetric_iv] if @base64 random_key = Base64.decode64(random_key) random_iv = Base64.decode64(random_iv) end cipher = Cipher.new(@symmetric_cipher) cipher.decrypt cipher.key = private_key.private_decrypt(random_key,@padding) cipher.iv = private_key.private_decrypt(random_iv,@padding) plaintext = cipher.update(ciphertext) plaintext << cipher.final else plaintext = private_key.private_decrypt(ciphertext,@padding) end else nil end end |
#encrypt(plaintext) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/strongbox/lock.rb', line 41 def encrypt plaintext ensure_required_columns if @ensure_required_columns unless @public_key raise StrongboxError.new("#{@instance.class} model does not have public key_file") end if !plaintext.blank? # Using a blank password in OpenSSL::PKey::RSA.new prevents reading # the private key if the file is a key pair public_key = get_rsa_key(@public_key,"") if @symmetric == :always cipher = Cipher.new(@symmetric_cipher) cipher.encrypt cipher.key = random_key = cipher.random_key cipher.iv = random_iv = cipher.random_iv ciphertext = cipher.update(plaintext) ciphertext << cipher.final encrypted_key = public_key.public_encrypt(random_key,@padding) encrypted_iv = public_key.public_encrypt(random_iv,@padding) if @base64 encrypted_key = Base64.encode64(encrypted_key) encrypted_iv = Base64.encode64(encrypted_iv) end @instance[@symmetric_key] = encrypted_key @instance[@symmetric_iv] = encrypted_iv else ciphertext = public_key.public_encrypt(plaintext,@padding) end ciphertext = Base64.encode64(ciphertext) if @base64 @instance[@name] = ciphertext end end |
#encrypt! ⇒ Object
36 37 38 39 |
# File 'lib/strongbox/lock.rb', line 36 def encrypt! encrypt @raw_content @raw_content = nil end |
#ensure_required_columns ⇒ Object
142 143 144 145 146 147 148 149 150 |
# File 'lib/strongbox/lock.rb', line 142 def ensure_required_columns columns = [@name.to_s] columns += [@symmetric_key, @symmetric_iv] if @symmetric == :always columns.each do |column| unless @instance.class.column_names.include? column raise StrongboxError.new("#{@instance.class} model does not have database column \"#{column}\"") end end end |
#length ⇒ Object
138 139 140 |
# File 'lib/strongbox/lock.rb', line 138 def length @size end |
#nil? ⇒ Boolean
130 131 132 |
# File 'lib/strongbox/lock.rb', line 130 def nil? @raw_content.nil? && @instance[@name].nil? end |
#size ⇒ Object
134 135 136 |
# File 'lib/strongbox/lock.rb', line 134 def size @size end |
#to_json(options = nil) ⇒ Object
121 122 123 |
# File 'lib/strongbox/lock.rb', line 121 def to_json( = nil) to_s end |
#to_s ⇒ Object
117 118 119 |
# File 'lib/strongbox/lock.rb', line 117 def to_s @raw_content || decrypt end |