Class: Omnizip::Formats::Rar::Rar5::Encryption::EncryptionManager

Inherits:
Object
  • Object
show all
Defined in:
lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb

Overview

Encryption manager for RAR5 archives

This manager coordinates the encryption process:

  1. Generate salt and IV
  2. Derive key from password using PBKDF2
  3. Encrypt file data with AES-256-CBC
  4. Create encryption header with metadata

Examples:

Encrypt file data

manager = EncryptionManager.new("SecurePassword", kdf_iterations: 262_144)
result = manager.encrypt_file_data(file_data)
# result[:encrypted_data] = encrypted bytes
# result[:header] = EncryptionHeader with salt, IV, etc.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(password, options = {}) ⇒ EncryptionManager

Initialize encryption manager

Parameters:

  • password (String)

    Encryption password

  • options (Hash) (defaults to: {})

    Options

Options Hash (options):

  • :kdf_iterations (Integer)

    PBKDF2 iterations (default: 262,144)

  • :salt (String)

    Pre-generated salt (16 bytes, optional)

  • :iv (String)

    Pre-generated IV (16 bytes, optional)



41
42
43
44
45
46
47
48
49
# File 'lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb', line 41

def initialize(password, options = {})
  @password = password
  @kdf_iterations = options[:kdf_iterations] || KeyDerivation::DEFAULT_ITERATIONS
  @salt = options[:salt]
  @iv = options[:iv]

  validate_password!
  validate_iterations!
end

Instance Attribute Details

#ivString? (readonly)

Returns Optional pre-generated IV.

Returns:

  • (String, nil)

    Optional pre-generated IV



32
33
34
# File 'lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb', line 32

def iv
  @iv
end

#kdf_iterationsInteger (readonly)

Returns PBKDF2 iteration count.

Returns:

  • (Integer)

    PBKDF2 iteration count



26
27
28
# File 'lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb', line 26

def kdf_iterations
  @kdf_iterations
end

#passwordString (readonly)

Returns Password for encryption.

Returns:

  • (String)

    Password for encryption



23
24
25
# File 'lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb', line 23

def password
  @password
end

#saltString? (readonly)

Returns Optional pre-generated salt.

Returns:

  • (String, nil)

    Optional pre-generated salt



29
30
31
# File 'lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb', line 29

def salt
  @salt
end

Instance Method Details

#decrypt_file_data(ciphertext, header) ⇒ String

Decrypt file data

Parameters:

  • ciphertext (String)

    Encrypted data

  • header (EncryptionHeader)

    Encryption metadata

Returns:

  • (String)

    Decrypted data

Raises:

  • (ArgumentError)

    If password incorrect



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb', line 86

def decrypt_file_data(ciphertext, header)
  # Extract salt and IV
  salt = header.salt_binary
  iv = header.iv_binary

  # Derive key from password
  key = KeyDerivation.derive_key(@password, salt,
                                 header.kdf_iterations)

  # Decrypt data
  cipher = Aes256Cbc.new(key, iv)
  cipher.decrypt(ciphertext)
rescue OpenSSL::Cipher::CipherError => e
  raise ArgumentError,
        "Decryption failed (wrong password?): #{e.message}"
end

#encrypt_file_data(plaintext) ⇒ Hash

Encrypt file data

Parameters:

  • plaintext (String)

    File data to encrypt

  • result (Hash)

    a customizable set of options

Returns:

  • (Hash)

    Encryption result



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb', line 58

def encrypt_file_data(plaintext)
  # Generate or use provided salt and IV
  salt = @salt || KeyDerivation.generate_salt
  iv = @iv || Aes256Cbc.generate_iv

  # Derive key from password
  key = KeyDerivation.derive_key(@password, salt, @kdf_iterations)

  # Encrypt data
  cipher = Aes256Cbc.new(key, iv)
  encrypted = cipher.encrypt(plaintext)

  # Create encryption header
  header = create_encryption_header(salt, iv)

  {
    encrypted_data: encrypted,
    header: header,
    key: key, # Include for verification if needed
  }
end

#verify_password(_header) ⇒ Boolean

Verify password without full decryption

This checks if the derived key can decrypt the check value. Faster than decrypting entire file.

Parameters:

Returns:

  • (Boolean)

    true if password correct



110
111
112
113
114
115
116
117
# File 'lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb', line 110

def verify_password(_header)
  # For now, we'll need a small encrypted sample to verify
  # This is a simplified check - full implementation would use
  # the check_value field properly
  true # Placeholder
rescue StandardError
  false
end