Class: Zip::AESDecrypter

Inherits:
Decrypter show all
Includes:
AESEncryption
Defined in:
lib/zip/crypto/aes_encryption.rb

Overview

:nodoc:

Constant Summary

Constants included from AESEncryption

Zip::AESEncryption::AUTHENTICATION_CODE_LENGTH, Zip::AESEncryption::BITS, Zip::AESEncryption::BLOCK_SIZE, Zip::AESEncryption::KEY_LENGTHS, Zip::AESEncryption::SALT_LENGTHS, Zip::AESEncryption::STRENGTHS, Zip::AESEncryption::STRENGTH_128_BIT, Zip::AESEncryption::STRENGTH_192_BIT, Zip::AESEncryption::STRENGTH_256_BIT, Zip::AESEncryption::VERIFIER_LENGTH, Zip::AESEncryption::VERSIONS, Zip::AESEncryption::VERSION_AE_1, Zip::AESEncryption::VERSION_AE_2

Instance Method Summary collapse

Methods included from AESEncryption

#gp_flags, #header_bytesize, #initialize

Instance Method Details

#check_integrity(auth_code) ⇒ Object

Raises:



115
116
117
# File 'lib/zip/crypto/aes_encryption.rb', line 115

def check_integrity(auth_code)
  raise Error, 'Integrity fault' if @hmac.digest[0...AUTHENTICATION_CODE_LENGTH] != auth_code
end

#decrypt(encrypted_data) ⇒ Object



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

def decrypt(encrypted_data)
  @hmac.update(encrypted_data)

  idx = 0
  decrypted_data = +''
  amount_to_read = encrypted_data.size

  while amount_to_read.positive?
    @cipher.iv = [@counter + 1].pack('Vx12')
    begin_index = BLOCK_SIZE * idx
    end_index = begin_index + [BLOCK_SIZE, amount_to_read].min
    decrypted_data << @cipher.update(encrypted_data[begin_index...end_index])
    amount_to_read -= BLOCK_SIZE
    @counter += 1
    idx += 1
  end

  # JRuby requires finalization of the cipher. This is a bug, as noted in
  # jruby/jruby-openssl#182 and jruby/jruby-openssl#183.
  decrypted_data << @cipher.final if defined?(JRUBY_VERSION)
  decrypted_data
end

#reset!(header) ⇒ Object

Raises:



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/zip/crypto/aes_encryption.rb', line 90

def reset!(header)
  raise Error, "Unsupported encryption AES-#{@bits}" unless STRENGTHS.include? @strength

  salt = header[0...@salt_length]
  pwd_verify = header[-VERIFIER_LENGTH..]
  key_material = OpenSSL::KDF.pbkdf2_hmac(
    @password,
    salt:       salt,
    iterations: 1000,
    length:     (2 * @key_length) + VERIFIER_LENGTH,
    hash:       'sha1'
  )
  enc_key = key_material[0...@key_length]
  enc_hmac_key = key_material[@key_length...(2 * @key_length)]
  enc_pwd_verify = key_material[-VERIFIER_LENGTH..]

  raise Error, 'Bad password' if enc_pwd_verify != pwd_verify

  @counter = 0
  @cipher = OpenSSL::Cipher::AES.new(@bits, :CTR)
  @cipher.decrypt
  @cipher.key = enc_key
  @hmac = OpenSSL::HMAC.new(enc_hmac_key, OpenSSL::Digest.new('SHA1'))
end