Class: Archive::Zip::Codec::TraditionalEncryption::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/archive/zip/codec/traditional_encryption.rb

Overview

Archive::Zip::Codec::TraditionalEncryption::Base provides some basic methods which are shared between Archive::Zip::Codec::TraditionalEncryption::Encrypt and Archive::Zip::Codec::TraditionalEncryption::Decrypt.

Do not use this class directly.

Direct Known Subclasses

Decrypt, Encrypt

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io, password, mtime) ⇒ Base

Creates a new instance of this class. io must be an IO-like object to be used as a delegate for IO operations. password should be the encryption key. mtime must be the last modified time of the entry to be encrypted/decrypted.



24
25
26
27
28
29
# File 'lib/archive/zip/codec/traditional_encryption.rb', line 24

def initialize(io, password, mtime)
  @io = io
  @password = password.nil? ? '' : password
  @mtime = mtime
  initialize_keys
end

Instance Attribute Details

#ioObject (readonly, protected)

The delegate IO-like object.



34
35
36
# File 'lib/archive/zip/codec/traditional_encryption.rb', line 34

def io
  @io
end

#mtimeObject (readonly, protected)

The last modified time of the entry being encrypted. This is used in the entryption header as a way to check the password.



39
40
41
# File 'lib/archive/zip/codec/traditional_encryption.rb', line 39

def mtime
  @mtime
end

#passwordObject (readonly, protected)

The encryption key.



36
37
38
# File 'lib/archive/zip/codec/traditional_encryption.rb', line 36

def password
  @password
end

Instance Method Details

#decrypt_byteObject (private)

Returns the next decryption byte based on the current keys.



68
69
70
71
# File 'lib/archive/zip/codec/traditional_encryption.rb', line 68

def decrypt_byte
  temp = (@key2 | 2) & 0x0000ffff
  ((temp * (temp ^ 1)) >> 8) & 0x000000ff
end

#initialize_keysObject (private)

Initializes the keys used for encrypting/decrypting data by setting the keys to well known values and then processing them with the password.



45
46
47
48
49
50
51
# File 'lib/archive/zip/codec/traditional_encryption.rb', line 45

def initialize_keys
  @key0 = 0x12345678
  @key1 = 0x23456789
  @key2 = 0x34567890
  @password.each_byte { |byte| update_keys(byte.chr) }
  nil
end

#update_keys(char) ⇒ Object (private)

Updates the keys following the ZIP specification using char, which must be a single byte String.



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/archive/zip/codec/traditional_encryption.rb', line 55

def update_keys(char)
  # For some reason not explained in the ZIP specification but discovered
  # in the source for InfoZIP, the old CRC value must first have its bits
  # flipped before processing.  The new CRC value must have its bits
  # flipped as well for storage and later use.  This applies to the
  # handling of @key0 and @key2.
  @key0 = ~Zlib.crc32(char, ~@key0)
  @key1 = ((@key1 + (@key0 & 0xff)) * 134775813 + 1) & 0xffffffff
  @key2 = ~Zlib.crc32((@key1 >> 24).chr, ~@key2)
  nil
end