Class: Pdfrb::Encryption::StandardSecurityHandler

Inherits:
SecurityHandler show all
Defined in:
lib/pdfrb/encryption/standard_security_handler.rb

Overview

Standard security handler (s7.6.3). V1..V6 / R2..R6. Owns per-document key derivation + per-object (de)cryption.

Supports:

V1, V2 + R2     : RC4 40-bit and 128-bit (PDF 1.4-1.5).
V4   + R4       : RC4 or AES-128 with crypt filters (PDF 1.5+).
V5   + R5       : AES-256 (PDF 1.7 Ext. 3).
V6   + R6       : AES-256 (PDF 2.0).

AES uses the openssl stdlib. RC4 is pure Ruby (TODO 119).

Instance Attribute Summary collapse

Attributes inherited from SecurityHandler

#document, #encrypt_dict

Instance Method Summary collapse

Methods inherited from SecurityHandler

#encrypted?, for, #initialize, register, registry

Constructor Details

This class inherits a constructor from Pdfrb::Encryption::SecurityHandler

Instance Attribute Details

#file_keyObject (readonly)

Returns the value of attribute file_key.



20
21
22
# File 'lib/pdfrb/encryption/standard_security_handler.rb', line 20

def file_key
  @file_key
end

#revisionObject (readonly)

Returns the value of attribute revision.



20
21
22
# File 'lib/pdfrb/encryption/standard_security_handler.rb', line 20

def revision
  @revision
end

#versionObject (readonly)

Returns the value of attribute version.



20
21
22
# File 'lib/pdfrb/encryption/standard_security_handler.rb', line 20

def version
  @version
end

Instance Method Details

#decrypt(bytes, oid, gen) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/pdfrb/encryption/standard_security_handler.rb', line 44

def decrypt(bytes, oid, gen)
  return bytes if @file_key.nil?

  case cipher_type
  when :rc4 then RC4.new(object_key(oid, gen, 16)).process(bytes)
  when :aes then AES.new(key_size: aes_key_bits, mode: :CBC).decrypt(bytes, object_key(oid, gen, aes_key_bits / 8 + 5).byteslice(0, aes_key_bits / 8))
  else bytes
  end
end

#encrypt(bytes, oid, gen) ⇒ Object



54
55
56
57
58
59
60
61
62
# File 'lib/pdfrb/encryption/standard_security_handler.rb', line 54

def encrypt(bytes, oid, gen)
  return bytes if @file_key.nil?

  case cipher_type
  when :rc4 then RC4.new(object_key(oid, gen, 16)).process(bytes)
  when :aes then AES.new(key_size: aes_key_bits, mode: :CBC).encrypt(bytes, object_key(oid, gen, aes_key_bits / 8 + 5).byteslice(0, aes_key_bits / 8), random_iv)
  else bytes
  end
end

#set_up_decryption(password: "") ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/pdfrb/encryption/standard_security_handler.rb', line 22

def set_up_decryption(password: "")
  @encrypt_dict = read_encrypt_dict
  return unless @encrypt_dict

  @version = @encrypt_dict[:V].to_i
  @revision = @encrypt_dict[:R].to_i
  id0 = document.trailer[:ID].to_a.first.b
  unless verify_password(password)
    raise Pdfrb::EncryptionError, "incorrect password"
  end
  derive_file_key(password, id0)
end

#verify_password(password) ⇒ Object

Verify the user (or owner) password. Returns true on match.



36
37
38
39
40
41
42
# File 'lib/pdfrb/encryption/standard_security_handler.rb', line 36

def verify_password(password)
  PasswordVerification.verify_user_password(
    password: password,
    encrypt_dict: @encrypt_dict,
    id0: document.trailer[:ID].to_a.first.b
  )
end