class Keepassx::Header
Constants
- ENCRYPTION_FLAGS
- SIGNATURES
Attributes
content_hash[RW]
encryption_iv[R]
entries_count[RW]
groups_count[RW]
Public Class Methods
new(header_bytes = nil)
click to toggle source
rubocop:disable Metrics/MethodLength
# 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).unpack1('L*') @signature2 = header_bytes.read(4).unpack1('L*') @flags = header_bytes.read(4).unpack1('L*') @version = header_bytes.read(4).unpack1('L*') @master_seed = header_bytes.read(16) @encryption_iv = header_bytes.read(16) @groups_count = header_bytes.read(4).unpack1('L*') @entries_count = header_bytes.read(4).unpack1('L*') @content_hash = header_bytes.read(32) @master_seed2 = header_bytes.read(32) @rounds = header_bytes.read(4).unpack1('L*') end end
Public Instance Methods
encode()
click to toggle source
Return encoded header
@return [String] Encoded header representation.
# 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()
click to toggle source
# 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)
click to toggle source
rubocop:disable Metrics/MethodLength
# 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?()
click to toggle source
rubocop:enable Metrics/MethodLength
# File lib/keepassx/header.rb, line 88 def valid? @signature1 == SIGNATURES[0] && @signature2 == SIGNATURES[1] end
Private Instance Methods
extract_keyfile_hash(keyfile_data)
click to toggle source
# File lib/keepassx/header.rb, line 147 def extract_keyfile_hash(keyfile_data) # Hex encoded key if keyfile_data.size == 64 [keyfile_data].pack('H*') # Raw key elsif keyfile_data.size == 32 keyfile_data else Digest::SHA2.new.update(keyfile_data).digest end end