Class: Kasefet::MasterKey

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

Constant Summary collapse

PBKDF2SaltLength =
32
CipherKeyLength =
32
CipherIVLength =
12
CipherAuthTagLength =
16

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file, passphrase: nil, keyfile: nil) ⇒ MasterKey

Returns a new instance of MasterKey.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/kasefet/master_key.rb', line 67

def initialize(file, passphrase: nil, keyfile: nil)
  @file = file

  # read in the key
  if File.exist?(@file)
    @key = File.binread(@file)
    if passphrase
      load_key_with_passphrase(passphrase)
    elsif keyfile
      load_key_with_keyfile(keyfile)
    end
  else
    # this is a new wallet, generate a random key
    cipher = OpenSSL::Cipher.new("aes-256-gcm")
    @key = cipher.random_key
    if passphrase
      store_key_with_passphrase(passphrase)
    elsif keyfile
      store_key_with_keyfile(keyfile)
    else
      File.binwrite(@file, @key)
    end
  end
end

Instance Attribute Details

#keyObject

Returns the value of attribute key.



92
93
94
# File 'lib/kasefet/master_key.rb', line 92

def key
  @key
end

Instance Method Details

#load_key_with_keyfile(keyfile) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/kasefet/master_key.rb', line 42

def load_key_with_keyfile(keyfile)
  master_key = File.binread(keyfile)
  cipher = OpenSSL::Cipher.new("aes-256-gcm")
  cipher.decrypt
  cipher.iv = @key[0...CipherIVLength]
  @key = @key[CipherIVLength..-1]
  cipher.auth_tag = @key[0...CipherAuthTagLength]
  @key = @key[CipherAuthTagLength..-1]
  cipher.key = master_key
  @key = cipher.update(@key) + cipher.final
end

#load_key_with_passphrase(passphrase) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/kasefet/master_key.rb', line 54

def load_key_with_passphrase(passphrase)
  cipher = OpenSSL::Cipher.new("aes-256-gcm")
  cipher.decrypt
  salt = @key[0...PBKDF2SaltLength]
  @key = @key[PBKDF2SaltLength..-1]
  cipher.iv = @key[0...CipherIVLength]
  @key = @key[CipherIVLength..-1]
  cipher.auth_tag = @key[0...CipherAuthTagLength]
  @key = @key[CipherAuthTagLength..-1]
  cipher.key = passphrase_to_key(passphrase, salt)
  @key = cipher.update(@key) + cipher.final
end

#passphrase_to_key(passphrase, salt) ⇒ Object



10
11
12
# File 'lib/kasefet/master_key.rb', line 10

def passphrase_to_key(passphrase, salt)
  return OpenSSL::PKCS5.pbkdf2_hmac_sha1(passphrase, salt, 20000, CipherKeyLength)
end

#store_key_with_keyfile(keyfile) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/kasefet/master_key.rb', line 29

def store_key_with_keyfile(keyfile)
  cipher = OpenSSL::Cipher.new("aes-256-gcm")
  master_key = File.binread(keyfile)
  cipher.encrypt
  cipher.iv = iv = cipher.random_iv
  cipher.key = master_key
  cipher.auth_data = ""
  encrypted_key = cipher.update(@key) + cipher.final
  encrypted_key = cipher.auth_tag + encrypted_key
  encrypted_key = iv + encrypted_key
  File.binwrite(@file, encrypted_key)
end

#store_key_with_passphrase(passphrase) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/kasefet/master_key.rb', line 14

def store_key_with_passphrase(passphrase)
  cipher = OpenSSL::Cipher.new("aes-256-gcm")
  salt = SecureRandom.random_bytes(PBKDF2SaltLength)
  master_key = passphrase_to_key(passphrase, salt)
  cipher.encrypt
  cipher.iv = iv = cipher.random_iv
  cipher.key = master_key
  cipher.auth_data = ""
  encrypted_key = cipher.update(@key) + cipher.final
  encrypted_key = cipher.auth_tag + encrypted_key
  encrypted_key = iv + encrypted_key
  encrypted_key = salt + encrypted_key
  File.binwrite(@file, encrypted_key)
end