• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

codeigniter4 / CodeIgniter4 / 20589198684

30 Dec 2025 04:55AM UTC coverage: 84.503% (-0.03%) from 84.53%
20589198684

Pull #9853

github

web-flow
Merge f1d8312ec into e2fc5243b
Pull Request #9853: feat(encryption): Add previous keys fallback feature

65 of 77 new or added lines in 5 files covered. (84.42%)

38 existing lines in 3 files now uncovered.

21572 of 25528 relevant lines covered (84.5%)

203.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.47
/system/Encryption/Handlers/OpenSSLHandler.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of CodeIgniter 4 framework.
7
 *
8
 * (c) CodeIgniter Foundation <admin@codeigniter.com>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace CodeIgniter\Encryption\Handlers;
15

16
use CodeIgniter\Encryption\Exceptions\EncryptionException;
17
use SensitiveParameter;
18

19
/**
20
 * Encryption handling for OpenSSL library
21
 *
22
 * @see \CodeIgniter\Encryption\Handlers\OpenSSLHandlerTest
23
 */
24
class OpenSSLHandler extends BaseHandler
25
{
26
    /**
27
     * Encryption key info.
28
     * This setting is only used by OpenSSLHandler.
29
     *
30
     * Set to 'encryption' for CI3 Encryption compatibility.
31
     */
32
    public string $encryptKeyInfo = '';
33

34
    /**
35
     * Authentication key info.
36
     * This setting is only used by OpenSSLHandler.
37
     *
38
     * Set to 'authentication' for CI3 Encryption compatibility.
39
     */
40
    public string $authKeyInfo = '';
41

42
    /**
43
     * HMAC digest to use
44
     *
45
     * @var string
46
     */
47
    protected $digest = 'SHA512';
48

49
    /**
50
     * List of supported HMAC algorithms
51
     *
52
     * @var array [name => digest size]
53
     */
54
    protected array $digestSize = [
55
        'SHA224' => 28,
56
        'SHA256' => 32,
57
        'SHA384' => 48,
58
        'SHA512' => 64,
59
    ];
60

61
    /**
62
     * Cipher to use
63
     *
64
     * @var string
65
     */
66
    protected $cipher = 'AES-256-CTR';
67

68
    /**
69
     * Starter key
70
     *
71
     * @var string
72
     */
73
    protected $key = '';
74

75
    /**
76
     * Whether the cipher-text should be raw. If set to false, then it will be base64 encoded.
77
     */
78
    protected bool $rawData = true;
79

80
    /**
81
     * {@inheritDoc}
82
     */
83
    public function encrypt(#[SensitiveParameter] $data, #[SensitiveParameter] $params = null)
84
    {
85
        // Allow key override
86
        if ($params !== null) {
6✔
87
            $this->key = is_array($params) && isset($params['key']) ? $params['key'] : $params;
5✔
88
        }
89

90
        if (empty($this->key)) {
6✔
91
            throw EncryptionException::forNeedsStarterKey();
1✔
92
        }
93

94
        // derive a secret key
95
        $encryptKey = \hash_hkdf($this->digest, $this->key, 0, $this->encryptKeyInfo);
5✔
96

97
        // basic encryption
98
        $iv = ($ivSize = \openssl_cipher_iv_length($this->cipher)) ? \openssl_random_pseudo_bytes($ivSize) : null;
5✔
99

100
        $data = \openssl_encrypt($data, $this->cipher, $encryptKey, OPENSSL_RAW_DATA, $iv);
5✔
101

102
        if ($data === false) {
5✔
103
            throw EncryptionException::forEncryptionFailed();
×
104
        }
105

106
        $result = $this->rawData ? $iv . $data : base64_encode($iv . $data);
5✔
107

108
        // derive a secret key
109
        $authKey = \hash_hkdf($this->digest, $this->key, 0, $this->authKeyInfo);
5✔
110

111
        $hmacKey = \hash_hmac($this->digest, $result, $authKey, $this->rawData);
5✔
112

113
        return $hmacKey . $result;
5✔
114
    }
115

116
    /**
117
     * {@inheritDoc}
118
     */
119
    public function decrypt($data, #[SensitiveParameter] $params = null)
120
    {
121
        $decryptParams = $params ?? $this->key;
8✔
122

123
        if (empty($decryptParams)) {
8✔
124
            throw EncryptionException::forNeedsStarterKey();
×
125
        }
126

127
        return $this->tryDecryptWithFallback($data, $decryptParams, function ($data, $params): string {
8✔
128
            $key = is_array($params) && isset($params['key']) ? $params['key'] : $params;
8✔
129

130
            $authKey = \hash_hkdf($this->digest, $key, 0, $this->authKeyInfo);
8✔
131

132
            $hmacLength = $this->rawData
8✔
133
                ? $this->digestSize[$this->digest]
6✔
134
                : $this->digestSize[$this->digest] * 2;
2✔
135

136
            $hmacKey  = self::substr($data, 0, $hmacLength);
8✔
137
            $data     = self::substr($data, $hmacLength);
8✔
138
            $hmacCalc = \hash_hmac($this->digest, $data, $authKey, $this->rawData);
8✔
139

140
            if (! hash_equals($hmacKey, $hmacCalc)) {
8✔
141
                throw EncryptionException::forAuthenticationFailed();
2✔
142
            }
143

144
            $data = $this->rawData ? $data : base64_decode($data, true);
6✔
145

146
            if ($ivSize = \openssl_cipher_iv_length($this->cipher)) {
6✔
147
                $iv   = self::substr($data, 0, $ivSize);
6✔
148
                $data = self::substr($data, $ivSize);
6✔
149
            } else {
NEW
150
                $iv = null;
×
151
            }
152

153
            // derive a secret key
154
            $encryptKey = \hash_hkdf($this->digest, $key, 0, $this->encryptKeyInfo);
6✔
155

156
            $decryptedData = \openssl_decrypt($data, $this->cipher, $encryptKey, OPENSSL_RAW_DATA, $iv);
6✔
157

158
            if ($decryptedData === false) {
6✔
NEW
159
                throw EncryptionException::forAuthenticationFailed();
×
160
            }
161

162
            return $decryptedData;
6✔
163
        });
8✔
164
    }
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc