Class: PDF::Reader::Rc4
- Inherits:
-
Object
- Object
- PDF::Reader::Rc4
- Defined in:
- lib/pdf/reader/rc4.rb
Overview
A minimal, self-contained implementation of the RC4 stream cipher, used to decrypt PDFs encrypted with the (legacy, but still spec-compliant) RC4 security handler. Vendored directly to avoid depending on the abandoned ruby-rc4 gem (last released 2012, archived since 2020, and missing license metadata in its gemspec).
Instance Method Summary collapse
-
#decrypt(data) ⇒ Object
(also: #encrypt)
RC4 encryption and decryption are the same operation (XOR with the keystream).
-
#initialize(key) ⇒ Rc4
constructor
A new instance of Rc4.
Constructor Details
#initialize(key) ⇒ Rc4
Returns a new instance of Rc4.
12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/pdf/reader/rc4.rb', line 12 def initialize(key) raise ArgumentError, "key must not be empty" if key.empty? @key = key.bytes #: Array[Integer] @s = (0..255).to_a #: Array[Integer] j = 0 256.times do |i| j = (j + @s.fetch(i) + @key.fetch(i % @key.length)) & 0xFF @s[i], @s[j] = @s.fetch(j), @s.fetch(i) end @i = 0 #: Integer @j = 0 #: Integer end |
Instance Method Details
#decrypt(data) ⇒ Object Also known as: encrypt
RC4 encryption and decryption are the same operation (XOR with the keystream).
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/pdf/reader/rc4.rb', line 28 def decrypt(data) out = "".b data = data.dup.force_encoding(::Encoding::ASCII_8BIT) data.each_byte do |byte| @i = (@i + 1) & 0xFF @j = (@j + @s.fetch(@i)) & 0xFF @s[@i], @s[@j] = @s.fetch(@j), @s.fetch(@i) k = @s.fetch((@s.fetch(@i) + @s.fetch(@j)) & 0xFF) out << (byte ^ k) end out end |