Class: HexaPDF::Encryption::RubyAES

Inherits:
Object
  • Object
show all
Includes:
AES
Defined in:
lib/hexapdf/encryption/ruby_aes.rb

Overview

Implementation of the general encryption algorithm AES.

Since this algorithm is implemented in pure Ruby, it is not very fast. Therefore the FastAES class based on OpenSSL should be used when possible.

For reference: This implementation is about 5000 times slower when decrypting and about 1800 times slower when encrypting than the FastAES version.

This implementation is using AES in Cipher Block Chaining (CBC) mode.

See: PDF2.0 s7.6.3

Constant Summary

Constants included from AES

AES::BLOCK_SIZE, AES::VALID_KEY_LENGTH

Instance Method Summary collapse

Methods included from AES

prepended

Constructor Details

#initialize(key, iv, mode) ⇒ RubyAES

Creates a new AES object using the given encryption key and initialization vector.

The mode must either be :encrypt or :decrypt.



62
63
64
65
66
67
# File 'lib/hexapdf/encryption/ruby_aes.rb', line 62

def initialize(key, iv, mode)
  @key = key
  @expanded_key_blocks = expand_key(@key)
  @prev_block = iv.bytes
  @mode = mode
end

Instance Method Details

#process(data) ⇒ Object

Encrypts or decrypts the given data whose length must be a multiple of BLOCK_SIZE.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/hexapdf/encryption/ruby_aes.rb', line 70

def process(data)
  data = data.bytes

  (data.size / BLOCK_SIZE).times do |i|
    block = data[i * BLOCK_SIZE, BLOCK_SIZE]

    if @mode == :encrypt
      xor_blocks(block, @prev_block) # CBC: XOR plain text block with previous cipher block
      send(@mode, block)
      @prev_block = block
    else
      prev = block.dup
      send(@mode, block)
      xor_blocks(block, @prev_block) # CBC: XOR plain text block with previous cipher block
      @prev_block = prev
    end

    data[i * BLOCK_SIZE, BLOCK_SIZE] = block
  end

  data.pack('C*')
end