Class: Keepassx::Header
- Inherits:
-
Object
- Object
- Keepassx::Header
- Defined in:
- lib/keepassx/header.rb
Constant Summary collapse
- ENCRYPTION_FLAGS =
[ [1, 'SHA2'], [2, 'Rijndael'], [2, 'AES'], [4, 'ArcFour'], [8, 'TwoFish'], ].freeze
- SIGNATURES =
[0x9AA2D903, 0xB54BFB65].freeze
Instance Attribute Summary collapse
-
#content_hash ⇒ Object
Returns the value of attribute content_hash.
-
#encryption_iv ⇒ Object
readonly
Returns the value of attribute encryption_iv.
-
#entries_count ⇒ Object
Returns the value of attribute entries_count.
-
#groups_count ⇒ Object
Returns the value of attribute groups_count.
Instance Method Summary collapse
-
#encode ⇒ String
Return encoded header.
- #encryption_type ⇒ Object
-
#final_key(master_key, keyfile_data = nil) ⇒ Object
rubocop:disable Metrics/MethodLength.
-
#initialize(header_bytes = nil) ⇒ Header
constructor
rubocop:disable Metrics/MethodLength.
- #valid? ⇒ Boolean
Constructor Details
#initialize(header_bytes = nil) ⇒ Header
rubocop:disable Metrics/MethodLength
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/keepassx/header.rb', line 58 def initialize(header_bytes = nil) if header_bytes.nil? @signature1 = SIGNATURES[0] @signature2 = SIGNATURES[1] @flags = 3 # SHA2 hashing, AES encryption @version = 0x30002 @master_seed = SecureRandom.random_bytes(16) @encryption_iv = SecureRandom.random_bytes(16) @groups_count = 0 @entries_count = 0 @master_seed2 = SecureRandom.random_bytes(32) @rounds = 50_000 else header_bytes = StringIO.new(header_bytes) @signature1 = header_bytes.read(4).unpack('L*').first @signature2 = header_bytes.read(4).unpack('L*').first @flags = header_bytes.read(4).unpack('L*').first @version = header_bytes.read(4).unpack('L*').first @master_seed = header_bytes.read(16) @encryption_iv = header_bytes.read(16) @groups_count = header_bytes.read(4).unpack('L*').first @entries_count = header_bytes.read(4).unpack('L*').first @content_hash = header_bytes.read(32) @master_seed2 = header_bytes.read(32) @rounds = header_bytes.read(4).unpack('L*').first end end |
Instance Attribute Details
#content_hash ⇒ Object
Returns the value of attribute content_hash.
54 55 56 |
# File 'lib/keepassx/header.rb', line 54 def content_hash @content_hash end |
#encryption_iv ⇒ Object (readonly)
Returns the value of attribute encryption_iv.
51 52 53 |
# File 'lib/keepassx/header.rb', line 51 def encryption_iv @encryption_iv end |
#entries_count ⇒ Object
Returns the value of attribute entries_count.
53 54 55 |
# File 'lib/keepassx/header.rb', line 53 def entries_count @entries_count end |
#groups_count ⇒ Object
Returns the value of attribute groups_count.
52 53 54 |
# File 'lib/keepassx/header.rb', line 52 def groups_count @groups_count end |
Instance Method Details
#encode ⇒ String
Return encoded header
129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/keepassx/header.rb', line 129 def encode [@signature1].pack('L*') << [@signature2].pack('L*') << [@flags].pack('L*') << [@version].pack('L*') << @master_seed << @encryption_iv << [@groups_count].pack('L*') << [@entries_count].pack('L*') << @content_hash << @master_seed2 << [@rounds].pack('L*') end |
#encryption_type ⇒ Object
93 94 95 96 97 98 |
# File 'lib/keepassx/header.rb', line 93 def encryption_type ENCRYPTION_FLAGS.each do |(flag_mask, encryption_type)| return encryption_type if @flags & flag_mask end 'Unknown' end |
#final_key(master_key, keyfile_data = nil) ⇒ Object
rubocop:disable Metrics/MethodLength
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/keepassx/header.rb', line 102 def final_key(master_key, keyfile_data = nil) key = Digest::SHA2.new.update(master_key).digest if keyfile_data keyfile_hash = extract_keyfile_hash(keyfile_data) key = master_key == '' ? keyfile_hash : Digest::SHA2.new.update(key + keyfile_hash).digest end aes = OpenSSL::Cipher.new('AES-256-ECB') aes.encrypt aes.key = @master_seed2 aes.padding = 0 @rounds.times do key = aes.update(key) + aes.final end key = Digest::SHA2.new.update(key).digest key = Digest::SHA2.new.update(@master_seed + key).digest key end |
#valid? ⇒ Boolean
88 89 90 |
# File 'lib/keepassx/header.rb', line 88 def valid? @signature1 == SIGNATURES[0] && @signature2 == SIGNATURES[1] end |