Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
Rc4
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
1 / 1
 crypt
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <nick@popphp.org>
8 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Pdf\Build\Security;
16
17/**
18 * RC4 stream cipher
19 *
20 * PHP has no built-in RC4 primitive (and OpenSSL's RC4 support is
21 * inconsistent across builds/deprecated), but ISO 32000's Algorithms 3/5/7
22 * for PDF revisions 2-4 require it to compute the /O and /U password
23 * dictionary entries - even when the actual page/stream content is
24 * encrypted with AES rather than RC4. This class is used only for that
25 * dictionary-entry math; it never touches page/stream content.
26 *
27 * @category   Pop
28 * @package    Pop\Pdf
29 * @author     Nick Sagona, III <nick@popphp.org>
30 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
31 * @license    https://www.popphp.org/license     New BSD License
32 * @version    6.2.0
33 */
34class Rc4
35{
36    /**
37     * RC4 is a symmetric stream cipher - this same method encrypts and
38     * decrypts, since both operations are "XOR with the same keystream."
39     *
40     * @param  string $key
41     * @param  string $data
42     * @return string
43     */
44    public static function crypt(string $key, string $data): string
45    {
46        $keyLength = strlen($key);
47        $s = range(0, 255);
48
49        $j = 0;
50        for ($i = 0; $i < 256; $i++) {
51            $j = ($j + $s[$i] + ord($key[$i % $keyLength])) % 256;
52            [$s[$i], $s[$j]] = [$s[$j], $s[$i]];
53        }
54
55        $result = '';
56        $i = 0;
57        $j = 0;
58        for ($n = 0, $len = strlen($data); $n < $len; $n++) {
59            $i = ($i + 1) % 256;
60            $j = ($j + $s[$i]) % 256;
61            [$s[$i], $s[$j]] = [$s[$j], $s[$i]];
62            $result .= chr(ord($data[$n]) ^ $s[($s[$i] + $s[$j]) % 256]);
63        }
64
65        return $result;
66    }
67}