Class: Kasefet::EncryptedFlatKV

Inherits:
FlatKV
  • Object
show all
Defined in:
lib/kasefet/encrypted_flat_kv.rb

Overview

FlatKV where values are stored encrypted on the disk

Constant Summary collapse

CipherIVLength =
12
CipherAuthTagLength =
16

Constants inherited from FlatKV

FlatKV::MagicNumber

Instance Attribute Summary collapse

Attributes inherited from FlatKV

#device_name, #extension, #root

Instance Method Summary collapse

Methods inherited from FlatKV

#[], #[]=, #dir_for_key, #file_for_key, #format_value, #read_value

Constructor Details

#initialize(cipher_key:, key_salt: nil, **options) ⇒ EncryptedFlatKV

Returns a new instance of EncryptedFlatKV.



11
12
13
14
15
16
# File 'lib/kasefet/encrypted_flat_kv.rb', line 11

def initialize(cipher_key:, key_salt: nil, **options)
  super(**options)
  @cipher = OpenSSL::Cipher.new("aes-256-gcm")
  @cipher_key = cipher_key
  @key_salt = key_salt
end

Instance Attribute Details

#cipher_keyObject

Returns the value of attribute cipher_key.



18
19
20
# File 'lib/kasefet/encrypted_flat_kv.rb', line 18

def cipher_key
  @cipher_key
end

#key_saltObject

Returns the value of attribute key_salt.



18
19
20
# File 'lib/kasefet/encrypted_flat_kv.rb', line 18

def key_salt
  @key_salt
end

Instance Method Details

#decrypt_value(encrypted_value, cipher_key) ⇒ Object



49
50
51
52
53
54
55
56
57
58
# File 'lib/kasefet/encrypted_flat_kv.rb', line 49

def decrypt_value(encrypted_value, cipher_key)
  @cipher.decrypt
  @cipher.key = cipher_key
  @cipher.iv = encrypted_value[0...CipherIVLength]
  encrypted_value = encrypted_value[CipherIVLength..-1]
  @cipher.auth_tag = encrypted_value[0...CipherAuthTagLength]
  encrypted_value = encrypted_value[CipherAuthTagLength..-1]
  value = @cipher.update(encrypted_value) + @cipher.final
  return value
end

#encrypt_value(value, cipher_key) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/kasefet/encrypted_flat_kv.rb', line 37

def encrypt_value(value, cipher_key)
  @cipher.encrypt
  @cipher.key = cipher_key
  iv = @cipher.random_iv
  @cipher.iv = iv
  @cipher.auth_data = ""
  encrypted_value = @cipher.update(value) + @cipher.final
  encrypted_value = @cipher.auth_tag + encrypted_value
  encrypted_value = iv + encrypted_value
  return encrypted_value
end

#key_to_digest(key) ⇒ Object



20
21
22
23
# File 'lib/kasefet/encrypted_flat_kv.rb', line 20

def key_to_digest(key)
  key = "#{@key_salt}/#{key}/#{@key_salt}" if @key_salt
  return super(key)
end

#read_file(file_path) ⇒ Object



60
61
62
63
64
# File 'lib/kasefet/encrypted_flat_kv.rb', line 60

def read_file(file_path)
  encrypted_contents = super(file_path)
  return nil if encrypted_contents.nil?
  return decrypt_value(encrypted_contents, @cipher_key)
end

#reencrypt_all_values!(new_key) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/kasefet/encrypted_flat_kv.rb', line 25

def reencrypt_all_values!(new_key)
  old_key = @cipher_key

  Dir[@root + "*" + "*" + "*"].each do |encrypted_file|
    old_encrypted_value = File.binread(encrypted_file)
    value = decrypt_value(old_encrypted_value, old_key)
    new_encrypted_value = encrypt_value(value, new_key)
    File.binwrite(encrypted_file, new_encrypted_value)
  end
  @cipher_key = new_key
end

#write_file(path, contents) ⇒ Object



66
67
68
# File 'lib/kasefet/encrypted_flat_kv.rb', line 66

def write_file(path, contents)
  return super(path, encrypt_value(contents, @cipher_key))
end