Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
11 / 11
CRAP
100.00% covered (success)
100.00%
1 / 1
AbstractEncrypter
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
11 / 11
19
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 setCipher
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getCipher
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasCipher
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setKey
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 getKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 hasKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAllKeys
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setPreviousKeys
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
 getPreviousKeys
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 hasPreviousKeys
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isAvailable
n/a
0 / 0
n/a
0 / 0
0
 isValid
n/a
0 / 0
n/a
0 / 0
0
 encrypt
n/a
0 / 0
n/a
0 / 0
0
 decrypt
n/a
0 / 0
n/a
0 / 0
0
1<?php
2/**
3 * Pop PHP Framework (https://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@noladev.com>
7 * @copyright  Copyright (c) 2009-2026 NOLA Interactive, LLC.
8 * @license    https://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Crypt\Encryption;
15
16/**
17 * Pop Crypt abstract encrypter
18 *
19 * @category   Pop
20 * @package    Pop\Crypt
21 * @author     Nick Sagona, III <dev@noladev.com>
22 * @copyright  Copyright (c) 2009-2026 NOLA Interactive, LLC.
23 * @license    https://www.popphp.org/license     New BSD License
24 * @version    3.0.0
25 */
26abstract class AbstractEncrypter
27{
28
29    /**
30     * Encryption cipher
31     * @var string
32     */
33    protected string $cipher = 'aes-256-cbc';
34
35    /**
36     * Encryption Key
37     * @var ?string
38     */
39    protected ?string $key = null;
40
41    /**
42     * Previous keys
43     * @var array
44     */
45    protected array $previousKeys = [];
46
47    /**
48     * Constructor
49     *
50     * Instantiate the Encrypter object
51     *
52     * @param  string $key
53     * @param  string $cipher
54     * @param  bool   $raw
55     * @throws Exception
56     */
57    public function __construct(string $key, string $cipher = 'aes-256-cbc', bool $raw = true)
58    {
59        if (!static::isValid($key, $cipher, $raw)) {
60            throw new Exception('Error: Invalid key or unsupported cipher.');
61        }
62        $this->setKey($key, $raw);
63        $this->setCipher($cipher);
64    }
65
66    /**
67     * Set cipher
68     *
69     * @param  string $cipher
70     * @return static
71     */
72    public function setCipher(string $cipher): static
73    {
74        $this->cipher = strtolower($cipher);
75        return $this;
76    }
77
78    /**
79     * Get cipher
80     *
81     * @return string
82     */
83    public function getCipher(): string
84    {
85        return $this->cipher;
86    }
87
88    /**
89     * Has cipher
90     *
91     * @return bool
92     */
93    public function hasCipher(): bool
94    {
95        return !empty($this->cipher);
96    }
97
98    /**
99     * Set key
100     *
101     * @param  string $key
102     * @param  bool   $raw
103     * @return static
104     */
105    public function setKey(string $key, bool $raw = true): static
106    {
107        $this->key = ($raw) ? $key : base64_decode($key);
108        return $this;
109    }
110
111    /**
112     * Get key
113     *
114     * @param  bool $raw
115     * @return string
116     */
117    public function getKey(bool $raw = false): string
118    {
119        return ($raw) ? $this->key : base64_encode($this->key);
120    }
121
122    /**
123     * Has key
124     *
125     * @return bool
126     */
127    public function hasKey(): bool
128    {
129        return !empty($this->key);
130    }
131
132    /**
133     * Get all keys
134     *
135     * @return array
136     */
137    public function getAllKeys(): array
138    {
139        return [$this->key, ...$this->previousKeys];
140    }
141
142    /**
143     * Set previous keys
144     *
145     * @param  array $previousKeys
146     * @param  bool  $raw
147     * @throws Exception
148     * @return static
149     */
150    public function setPreviousKeys(array $previousKeys, bool $raw = true): static
151    {
152        if (!empty($this->cipher)) {
153            foreach ($previousKeys as $i => $previousKey) {
154                if (!$raw) {
155                    $previousKey = base64_decode($previousKey);
156                }
157                if (!static::isValid($previousKey, $this->cipher)) {
158                    throw new Exception('Error: Invalid key or unsupported cipher.');
159                }
160                $this->previousKeys[] = $previousKey;
161            }
162        }
163
164        return $this;
165    }
166
167    /**
168     * Get previous keys
169     *
170     * @param  bool $raw
171     * @return array
172     */
173    public function getPreviousKeys(bool $raw = false): array
174    {
175        if (!$raw) {
176            return array_map(function ($value) {
177                return base64_encode($value);
178            }, $this->previousKeys);
179        } else {
180            return $this->previousKeys;
181        }
182    }
183
184    /**
185     * Has previous keys
186     *
187     * @return bool
188     */
189    public function hasPreviousKeys(): bool
190    {
191        return !empty($this->previousKeys);
192    }
193
194    /**
195     * Determine if the cipher is available
196     *
197     * @param  string $cipher
198     * @return bool
199     */
200    abstract public static function isAvailable(string $cipher);
201
202    /**
203     * Determine if the key and cipher combination is valid
204     *
205     * @param  string $key
206     * @param  string $cipher
207     * @param  bool   $raw
208     * @return bool
209     */
210    abstract public static function isValid(string $key, string $cipher, bool $raw = true): bool;
211
212    /**
213     * Encrypt value
214     *
215     * @param  mixed $value
216     * @return string
217     */
218    abstract public function encrypt(#[\SensitiveParameter] mixed $value): string;
219
220    /**
221     * Decrypt value
222     *
223     * @param  string $payload
224     * @return mixed
225     */
226    abstract public function decrypt(string $payload): mixed;
227
228}