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'] ]
- FIELDS =
[ :signature1, :signature2, :flags, :version, :master_seed, :encryption_iv, :group_number, :entry_number, :contents_hash, :master_seed2, :rounds ]
- SIGNATURES =
[0x9AA2D903, 0xB54BFB65]
Instance Attribute Summary collapse
-
#contents_hash ⇒ Object
Returns the value of attribute contents_hash.
-
#encryption_iv ⇒ Object
Returns the value of attribute encryption_iv.
-
#entry_number ⇒ Object
Returns the value of attribute entry_number.
-
#flags ⇒ Object
readonly
Returns the value of attribute flags.
-
#group_number ⇒ Object
Returns the value of attribute group_number.
-
#master_seed ⇒ Object
readonly
Returns the value of attribute master_seed.
-
#master_seed2 ⇒ Object
readonly
Returns the value of attribute master_seed2.
-
#rounds ⇒ Object
readonly
Returns the value of attribute rounds.
-
#signature1 ⇒ Object
readonly
Returns the value of attribute signature1.
-
#signature2 ⇒ Object
readonly
Returns the value of attribute signature2.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Instance Method Summary collapse
-
#encode ⇒ String
Return encoded header.
- #encryption_type ⇒ Object
- #final_key(master_key, keyfile_data = nil) ⇒ Object
-
#initialize(header_bytes = nil) ⇒ Header
constructor
A new instance of Header.
- #length ⇒ Object
- #valid? ⇒ Boolean
Constructor Details
#initialize(header_bytes = nil) ⇒ Header
Returns a new instance of Header.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/keepassx/header.rb', line 67 def initialize(header_bytes = nil) if header_bytes.nil? self.signature1, self.signature2 = SIGNATURES self.flags = 3 # SHA2 hashing, AES encryption self.version = 0x30002 self.master_seed = SecureRandom.random_bytes(16) self.encryption_iv = SecureRandom.random_bytes(16) self.master_seed2 = SecureRandom.random_bytes(32) self.group_number = 0 self.entry_number = 0 self.rounds = 50000 else header_bytes = StringIO.new header_bytes self.signature1 = header_bytes.read(4).unpack('L*').first self.signature2 = header_bytes.read(4).unpack('L*').first self.flags = header_bytes.read(4).unpack('L*').first self.version = header_bytes.read(4).unpack('L*').first self.master_seed = header_bytes.read(16) self.encryption_iv = header_bytes.read(16) self.group_number = header_bytes.read(4).unpack('L*').first self.entry_number = header_bytes.read(4).unpack('L*').first self.contents_hash = header_bytes.read(32) self.master_seed2 = header_bytes.read(32) self.rounds = header_bytes.read(4).unpack('L*').first end end |
Instance Attribute Details
#contents_hash ⇒ Object
Returns the value of attribute contents_hash.
62 63 64 |
# File 'lib/keepassx/header.rb', line 62 def contents_hash @contents_hash end |
#encryption_iv ⇒ Object
Returns the value of attribute encryption_iv.
62 63 64 |
# File 'lib/keepassx/header.rb', line 62 def encryption_iv @encryption_iv end |
#entry_number ⇒ Object
Returns the value of attribute entry_number.
62 63 64 |
# File 'lib/keepassx/header.rb', line 62 def entry_number @entry_number end |
#flags ⇒ Object
Returns the value of attribute flags.
63 64 65 |
# File 'lib/keepassx/header.rb', line 63 def flags @flags end |
#group_number ⇒ Object
Returns the value of attribute group_number.
62 63 64 |
# File 'lib/keepassx/header.rb', line 62 def group_number @group_number end |
#master_seed ⇒ Object
Returns the value of attribute master_seed.
63 64 65 |
# File 'lib/keepassx/header.rb', line 63 def master_seed @master_seed end |
#master_seed2 ⇒ Object
Returns the value of attribute master_seed2.
63 64 65 |
# File 'lib/keepassx/header.rb', line 63 def master_seed2 @master_seed2 end |
#rounds ⇒ Object
Returns the value of attribute rounds.
63 64 65 |
# File 'lib/keepassx/header.rb', line 63 def rounds @rounds end |
#signature1 ⇒ Object
Returns the value of attribute signature1.
63 64 65 |
# File 'lib/keepassx/header.rb', line 63 def signature1 @signature1 end |
#signature2 ⇒ Object
Returns the value of attribute signature2.
63 64 65 |
# File 'lib/keepassx/header.rb', line 63 def signature2 @signature2 end |
#version ⇒ Object
Returns the value of attribute version.
63 64 65 |
# File 'lib/keepassx/header.rb', line 63 def version @version end |
Instance Method Details
#encode ⇒ String
Return encoded header
109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/keepassx/header.rb', line 109 def encode [signature1].pack('L*') << [signature2].pack('L*') << [flags].pack('L*') << [version].pack('L*') << master_seed << encryption_iv << [group_number].pack('L*') << [entry_number].pack('L*') << contents_hash << master_seed2 << [rounds].pack('L*') end |
#encryption_type ⇒ Object
130 131 132 133 134 135 |
# File 'lib/keepassx/header.rb', line 130 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
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/keepassx/header.rb', line 138 def final_key(master_key, keyfile_data=nil) key = Digest::SHA2.new.update(master_key).digest if keyfile_data if keyfile_data.size == 64 # Hex encoded key keyfile_hash = [keyfile_data].pack("H*") elsif keyfile_data.size == 32 # Raw key keyfile_hash = keyfile_data else keyfile_hash = Digest::SHA2.new.update(keyfile_data).digest end if master_key == "" key = keyfile_hash else key = Digest::SHA2.new.update(key + keyfile_hash).digest end end aes = OpenSSL::Cipher::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 Digest::SHA2.new.update(master_seed + key).digest end |
#length ⇒ Object
97 98 99 100 101 102 103 |
# File 'lib/keepassx/header.rb', line 97 def length length = 0 FIELDS.each do |field| length += field.length end length end |
#valid? ⇒ Boolean
125 126 127 |
# File 'lib/keepassx/header.rb', line 125 def valid? signature1 == SIGNATURES[0] && signature2 == SIGNATURES[1] end |