Module: Xlsxrb::Ooxml::Crypto

Defined in:
lib/xlsxrb/ooxml/crypto.rb,
lib/xlsxrb/ooxml/crypto/agile.rb,
lib/xlsxrb/ooxml/crypto/standard.rb,
sig/generated/xlsxrb/ooxml/crypto.rbs,
sig/generated/xlsxrb/ooxml/crypto/agile.rbs,
sig/generated/xlsxrb/ooxml/crypto/standard.rbs

Overview

High-level encryption and decryption facade for [MS-OFFCRYPTO] Excel document protection.

Defined Under Namespace

Classes: Agile, Standard

Class Method Summary collapse

Class Method Details

.decrypt(cfb_data, password) ⇒ Object

Decrypts an encrypted XLSX (CFB) package with the given password.

Parameters:

  • cfb_data (Object)
  • password (Object)

Returns:

  • (Object)


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/xlsxrb/ooxml/crypto.rb', line 27

def decrypt(cfb_data, password)
  raise Xlsxrb::EncryptedFileError, "Password is required to decrypt this file" if password.nil? || password.to_s.empty?

  reader = Cfb::Reader.new(cfb_data)
  encryption_info = reader.read_stream("EncryptionInfo")
  encrypted_package = reader.read_stream("EncryptedPackage")

  raise Xlsxrb::DecryptionError, "Missing EncryptionInfo or EncryptedPackage stream" if encryption_info.nil? || encrypted_package.nil?

  major, minor = encryption_info[0, 4].unpack("vv")
  if major == 4 && minor == 4
    Agile.decrypt(encryption_info, encrypted_package, password)
  elsif minor == 2
    Standard.decrypt(encryption_info, encrypted_package, password)
  else
    raise Xlsxrb::DecryptionError, "Unsupported encryption version #{major}.#{minor}"
  end
end

.encrypt(plain_zip_data, password, mode: :standard) ⇒ Object

Encrypts a plain ZIP payload with the given password into an encrypted CFB package.

Parameters:

  • plain_zip_data (Object)
  • password (Object)
  • mode: (Object) (defaults to: :standard)

Returns:

  • (Object)


47
48
49
50
51
52
53
54
55
56
# File 'lib/xlsxrb/ooxml/crypto.rb', line 47

def encrypt(plain_zip_data, password, mode: :standard)
  return plain_zip_data if password.nil? || password.to_s.empty?

  streams = if mode == :agile
              Agile.encrypt(plain_zip_data, password)
            else
              Standard.encrypt(plain_zip_data, password)
            end
  Cfb::Writer.write(streams)
end

.encrypted?(data) ⇒ Object

Checks if the binary data is an encrypted Compound File Binary package.

Parameters:

  • data (Object)

Returns:

  • (Object)


15
16
17
18
19
20
21
22
23
24
# File 'lib/xlsxrb/ooxml/crypto.rb', line 15

def encrypted?(data)
  return false unless Cfb::Reader.cfb?(data)

  begin
    reader = Cfb::Reader.new(data)
    reader.stream_names.any? { |n| n.casecmp?("EncryptionInfo") }
  rescue StandardError
    false
  end
end