Class: Aspera::Keychain::EncryptedHash
- Inherits:
-
Object
- Object
- Aspera::Keychain::EncryptedHash
- Defined in:
- lib/aspera/keychain/encrypted_hash.rb
Overview
Manage secrets in a simple Hash
Constant Summary collapse
- CIPHER_NAME =
'aes-256-cbc'- CONTENT_KEYS =
i[label username password url description].freeze
Instance Method Summary collapse
- #delete(label:) ⇒ Object
- #get(label:, exception: true) ⇒ Object
-
#initialize(path, current_password) ⇒ EncryptedHash
constructor
A new instance of EncryptedHash.
- #list ⇒ Object
- #password=(new_password) ⇒ Object
- #save ⇒ Object
- #set(options) ⇒ Object
Constructor Details
#initialize(path, current_password) ⇒ EncryptedHash
Returns a new instance of EncryptedHash.
14 15 16 17 18 19 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 14 def initialize(path, current_password) @path = path self.password = current_password raise 'path to vault file shall be String' unless @path.is_a?(String) @all_secrets = File.exist?(@path) ? YAML.load_stream(@cipher.decrypt(File.read(@path))).first : {} end |
Instance Method Details
#delete(label:) ⇒ Object
56 57 58 59 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 56 def delete(label:) @all_secrets.delete(label) save end |
#get(label:, exception: true) ⇒ Object
61 62 63 64 65 66 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 61 def get(label:, exception: true) raise "Label not found: #{label}" unless @all_secrets.key?(label) || !exception result = @all_secrets[label].clone result[:label] = label if result.is_a?(Hash) return result end |
#list ⇒ Object
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 45 def list result = [] @all_secrets.each do |label, values| normal = values.symbolize_keys normal[:label] = label CONTENT_KEYS.each{|k|normal[k] = '' unless normal.key?(k)} result.push(normal) end return result end |
#password=(new_password) ⇒ Object
21 22 23 24 25 26 27 28 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 21 def password=(new_password) # number of bits in second position key_bytes = CIPHER_NAME.split('-')[1].to_i / Environment::BITS_PER_BYTE # derive key from passphrase, add trailing zeros key = "#{new_password}#{"\x0" * key_bytes}"[0..(key_bytes - 1)] Log.log.debug{"key=[#{key}],#{key.length}"} SymmetricEncryption.cipher = @cipher = SymmetricEncryption::Cipher.new(cipher_name: CIPHER_NAME, key: key, encoding: :none) end |
#save ⇒ Object
30 31 32 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 30 def save File.write(@path, @cipher.encrypt(YAML.dump(@all_secrets)), encoding: 'BINARY') end |
#set(options) ⇒ Object
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/aspera/keychain/encrypted_hash.rb', line 34 def set() raise 'options shall be Hash' unless .is_a?(Hash) unsupported = .keys - CONTENT_KEYS .each_value {|v| raise 'value must be String' unless v.is_a?(String)} raise "unsupported options: #{unsupported}" unless unsupported.empty? label = .delete(:label) raise "secret #{label} already exist, delete first" if @all_secrets.key?(label) @all_secrets[label] = .symbolize_keys save end |