Skip to content

Commit 2570a7c

Browse files
committed
Update of hmac encryption config values
1 parent 795a214 commit 2570a7c

File tree

8 files changed

+101
-90
lines changed

8 files changed

+101
-90
lines changed

UPGRADING.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,19 @@ protected function redirectToDeniedUrl(): RedirectResponse
5353
#### Config\AuthToken
5454

5555
If you are using the HMAC authentication you need to update the encryption settings in **app/Config/AuthToken.php**.
56-
You will need to update and set the encryption key `$hmacEncryption['key']`. This should be set using **.env** and/or system
57-
environment variables. Instructions on how to do that can be found in the
56+
You will need to update and set the encryption key in `$hmacEncryptionKeys`. This should be set using **.env** and/or
57+
system environment variables. Instructions on how to do that can be found in the
5858
[Setting Your Encryption Key](https://codeigniter.com/user_guide/libraries/encryption.html#setting-your-encryption-key)
5959
section of the CodeIgniter 4 documentation and in [HMAC SHA256 Token Authenticator](./docs/references/authentication/hmac.md#hmac-secret-key-encryption).
6060

61-
You also may wish to adjust the default Driver `$hmacEncryption['driver']` and the default Digest `$hmacEncryption['digest']`,
62-
these currently default to `'OpenSSL'` and `'SHA512'` respectively.
61+
You also may wish to adjust the default Driver `$hmacEncryptionDefaultDriver` and the default Digest
62+
`$hmacEncryptionDefaultDigest`, these currently default to `'OpenSSL'` and `'SHA512'` respectively.
6363

6464
#### Encrypt Existing Keys
6565

66-
After updating the `$hmacEncryption['key']` value, you will need to run `php spark shield:hmac encrypt` in order to encrypt
67-
any existing HMAC tokens. This only needs to be run if you have existing unencrypted HMAC secretKeys in stored in the
68-
database.
66+
After updating the key in `$hmacEncryptionKeys` value, you will need to run `php spark shield:hmac encrypt` in order
67+
to encrypt any existing HMAC tokens. This only needs to be run if you have existing unencrypted HMAC secretKeys in
68+
stored in the database.
6969

7070
## Version 1.0.0-beta.6 to 1.0.0-beta.7
7171

docs/guides/api_hmac_keys.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,13 @@ $user->revokeAllHmacTokens();
9191
## HMAC Secret Key Encryption
9292

9393
The HMAC Secret Key is stored encrypted. Before you start using HMAC, you will need to set/override the encryption key
94-
`$hmacEncryption['key']` in **app/Config/AuthToken.php**. This should be set using **.env** and/or system environment variables.
95-
Instructions on how to do that can be found in the
94+
in `$hmacEncryptionKeys` in **app/Config/AuthToken.php**. This should be set using **.env** and/or system
95+
environment variables. Instructions on how to do that can be found in the
9696
[Setting Your Encryption Key](https://codeigniter.com/user_guide/libraries/encryption.html#setting-your-encryption-key)
9797
section of the CodeIgniter 4 documentation.
9898

99-
You will also be able to adjust the default Driver `$hmacEncryption['driver']` and the default Digest
100-
`$hmacEncryption['digest']`, these default to `'OpenSSL'` and `'SHA512'` respectively.
99+
You will also be able to adjust the default Driver `$hmacEncryptionDefaultDriver` and the default Digest
100+
`$hmacEncryptionDefaultDigest`, these default to `'OpenSSL'` and `'SHA512'` respectively.
101101

102102
See [HMAC SHA256 Token Authenticator](../references/authentication/hmac.md#hmac-secret-key-encryption) for additional
103103
details on setting these values.

docs/references/authentication/hmac.md

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -160,47 +160,48 @@ if ($user->hmacTokenCant('forums.manage')) {
160160
## HMAC Secret Key Encryption
161161

162162
The HMAC Secret Key is stored encrypted. Before you start using HMAC, you will need to set/override the encryption key
163-
`$hmacEncryption['key']` in **app/Config/AuthToken.php**. This should be set using **.env** and/or system environment variables.
164-
Instructions on how to do that can be found in the
163+
in `$hmacEncryptionKeys` in **app/Config/AuthToken.php**. This should be set using **.env** and/or system
164+
environment variables. Instructions on how to do that can be found in the
165165
[Setting Your Encryption Key](https://codeigniter.com/user_guide/libraries/encryption.html#setting-your-encryption-key)
166166
section of the CodeIgniter 4 documentation.
167167

168-
You will also be able to adjust the default Driver `$hmacEncryption['driver']` and the default Digest
169-
`$hmacEncryption['digest']`, these default to `'OpenSSL'` and `'SHA512'` respectively. All three properties (`$hmacEncryption['key']`,
170-
`$hmacEncryption['driver']`, and `$hmacEncryption['digest']`) are set in array format (see below).
168+
You will also be able to adjust the default Driver `$hmacEncryptionDefaultDriver` and the default Digest
169+
`$hmacEncryptionDefaultDigest`, these default to `'OpenSSL'` and `'SHA512'` respectively. These can also be
170+
overridden for an individual key by including them in the keys array.
171171

172172
```php
173-
public array $hmacEncryption = [
174-
'key' => [
175-
'k1' => 'hex2bin:923dfab5ddca0c7784c2c388a848a704f5e048736c1a852c862959da62ade8c7',
173+
public array $hmacEncryptionKeys = [
174+
'k1' => [
175+
'key' => 'hex2bin:923dfab5ddca0c7784c2c388a848a704f5e048736c1a852c862959da62ade8c7',
176176
],
177-
'driver' => ['k1' => 'OpenSSL'],
178-
'digest' => ['k1' => 'SHA512'],
179-
'currentKey' => 'k1',
180177
];
178+
179+
public string $hmacEncryptionCurrentKey = 'k1';
180+
public string $hmacEncryptionDefaultDriver = 'OpenSSL';
181+
public string $hmacEncryptionDefaultDigest = 'SHA512';
181182
```
182183

183-
When it is time to update your encryption keys you will need to add an additional key to the above arrays. Then adjust
184-
the `$hmacEncryption['currentKey']` to point at the new key. After the new encryption key is in place, run
185-
`php spark shield:hmac reencrypt` to re-encrypt all existing keys with the new encryption key. You will need to leave
186-
the old key in the array as it will be used read the existing 'Secret Keys' during re-encryption.
184+
When it is time to update your encryption keys you will need to add an additional key to the above
185+
`$hmacEncryptionKeys` array. Then adjust the `$hmacEncryptionCurrentKey` to point at the new key. After the new
186+
encryption key is in place, run `php spark shield:hmac reencrypt` to re-encrypt all existing keys with the new
187+
encryption key. You will need to leave the old key in the array as it will be used read the existing 'Secret Keys'
188+
during re-encryption.
187189

188190
```php
189-
public array $hmacEncryption = [
190-
'key' => [
191-
'k1' => 'hex2bin:923dfab5ddca0c7784c2c388a848a704f5e048736c1a852c862959da62ade8c7',
192-
'k2' => 'hex2bin:451df599363b19be1434605fff8556a0bbfc50bede1bb33793dcde4d97fce4b0',
193-
],
194-
'driver' => [
195-
'k1' => 'OpenSSL',
196-
'k2' => 'OpenSSL',
191+
public array $hmacEncryptionKeys = [
192+
'k1' => [
193+
'key' => 'hex2bin:923dfab5ddca0c7784c2c388a848a704f5e048736c1a852c862959da62ade8c7',
197194
],
198-
'digest' => [
199-
'k1' => 'SHA512',
200-
'k2' => 'SHA512',
195+
'k2' => [
196+
'key' => 'hex2bin:451df599363b19be1434605fff8556a0bbfc50bede1bb33793dcde4d97fce4b0',
197+
'digest' => 'SHA256',
201198
],
202-
'currentKey' => 'k2',
203199
];
200+
201+
public string $hmacEncryptionCurrentKey = 'k2';
202+
public string $hmacEncryptionDefaultDriver = 'OpenSSL';
203+
public string $hmacEncryptionDefaultDigest = 'SHA512';
204+
204205
```
205206

206207
```console
@@ -211,10 +212,8 @@ You can (and should) set these values using environment variable and/or the **.e
211212
the values as JSON strings:
212213

213214
```text
214-
authtoken.hmacEncryption.key = '{"k1":"hex2bin:923dfab5ddca0c7784c2c388a848a704f5e048736c1a852c862959da62ade8c7","k2":"hex2bin:451df599363b19be1434605fff8556a0bbfc50bede1bb33793dcde4d97fce4b0"}'
215-
authtoken.hmacEncryption.driver = '{"k1":"OpenSSL","k2":"OpenSSL"}'
216-
authtoken.hmacEncryption.digest = '{"k1":"SHA512","k2":"SHA512"}'
217-
authtoken.hmacEncryption.currentKey = k2
215+
authtoken.hmacEncryptionKeys = '{"k1":{"key":"hex2bin:923dfab5ddca0c7784c2c388a848a704f5e048736c1a852c862959da62ade8c7"},"k2":{"key":"hex2bin:451df599363b19be1434605fff8556a0bbfc50bede1bb33793dcde4d97fce4b0"}}'
216+
authtoken.hmacEncryptionCurrentKey = k2
218217
```
219218

220219
Depending on the set length of the Secret Key and the type of encryption used, it is possible for the encrypted value to

phpunit.xml.dist

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,7 @@
9494
<env name="COMPOSER_DISABLE_XDEBUG_WARN" value="1"/>
9595

9696
<!-- Default HMAC encryption key -->
97-
<env name="authtoken.hmacEncryption.key" value="{&quot;k1&quot;:&quot;hex2bin:178ed94fd0b6d57dd31dd6b22fc601fab8ad191efac165a5f3f30a8ac09d813d&quot;,&quot;k2&quot;:&quot;hex2bin:b0ab85bd0320824c496db2f40eb47c8712a6dfcfdf99b805988e22bdea6b9203&quot;}"/>
98-
<env name="authtoken.hmacEncryption.driver" value="{&quot;k1&quot;:&quot;OpenSSL&quot;,&quot;k2&quot;:&quot;OpenSSL&quot;}"/>
99-
<env name="authtoken.hmacEncryption.digest" value="{&quot;k1&quot;:&quot;SHA512&quot;,&quot;k2&quot;:&quot;SHA512&quot;}"/>
97+
<env name="authtoken.hmacEncryptionKeys" value="{&quot;k1&quot;:{&quot;key&quot;:&quot;hex2bin:178ed94fd0b6d57dd31dd6b22fc601fab8ad191efac165a5f3f30a8ac09d813d&quot;},&quot;k2&quot;:{&quot;key&quot;:&quot;hex2bin:b0ab85bd0320824c496db2f40eb47c8712a6dfcfdf99b805988e22bdea6b9203&quot;}}"/>
10098

10199
<!-- Database configuration -->
102100
<env name="database.tests.strictOn" value="true"/>

src/Authentication/HMAC/HmacEncrypter.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function __construct()
4040
{
4141
$this->authConfig = config('AuthToken');
4242

43-
$this->getEncrypter($this->authConfig->hmacEncryption['currentKey']);
43+
$this->getEncrypter($this->authConfig->hmacEncryptionCurrentKey);
4444
}
4545

4646
/**
@@ -77,7 +77,7 @@ public function decrypt(string $encString): string
7777
*/
7878
public function encrypt(string $rawString): string
7979
{
80-
$currentKey = $this->authConfig->hmacEncryption['currentKey'];
80+
$currentKey = $this->authConfig->hmacEncryptionCurrentKey;
8181

8282
$encryptedString = '$b6$' . $currentKey . '$' . base64_encode($this->encrypter[$currentKey]->encrypt($rawString));
8383

@@ -101,7 +101,7 @@ public function isEncrypted(string $string): bool
101101
*/
102102
public function isEncryptedWithCurrentKey(string $string): bool
103103
{
104-
$currentKey = $this->authConfig->hmacEncryption['currentKey'];
104+
$currentKey = $this->authConfig->hmacEncryptionCurrentKey;
105105

106106
return preg_match('/^\$b6\$' . $currentKey . '\$/', $string) === 1;
107107
}
@@ -126,15 +126,15 @@ public function generateSecretKey(): string
126126
private function getEncrypter(string $encrypterKey): EncrypterInterface
127127
{
128128
if (! isset($this->encrypter[$encrypterKey])) {
129-
if (! isset($this->authConfig->hmacEncryption['key'][$encrypterKey])) {
129+
if (! isset($this->authConfig->hmacEncryptionKeys[$encrypterKey]['key'])) {
130130
throw new RuntimeException('Encryption key does not exist.');
131131
}
132132

133133
$config = new Encryption();
134134

135-
$config->key = $this->authConfig->hmacEncryption['key'][$encrypterKey];
136-
$config->driver = $this->authConfig->hmacEncryption['driver'][$encrypterKey];
137-
$config->digest = $this->authConfig->hmacEncryption['digest'][$encrypterKey];
135+
$config->key = $this->authConfig->hmacEncryptionKeys[$encrypterKey]['key'];
136+
$config->driver = $this->authConfig->hmacEncryptionKeys[$encrypterKey]['driver'] ?? $this->authConfig->hmacEncryptionDefaultDriver;
137+
$config->digest = $this->authConfig->hmacEncryptionKeys[$encrypterKey]['digest'] ?? $this->authConfig->hmacEncryptionDefaultDigest;
138138

139139
$this->encrypter[$encrypterKey] = Services::encrypter($config);
140140
}

src/Config/AuthToken.php

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,36 +76,55 @@ class AuthToken extends BaseAuthToken
7676
* --------------------------------------------------------------------
7777
* This sets the key to be used when encrypting a user's HMAC Secret Key.
7878
*
79-
* 'key' is an array of keys which will facilitate key rotation. Valid
79+
* 'keys' is an array of keys which will facilitate key rotation. Valid
8080
* keyTitles must include only [a-zA-Z0-9_] and should be kept to a
8181
* max of 8 characters.
8282
*
83-
* 'driver' is used when encrypting HMAC Secret Key for storage.
84-
* Available drivers:
85-
* - OpenSSL
86-
* - Sodium
87-
*
88-
* This is an array of drivers values. The keys MUST match and correlate
89-
* to the 'key' array keys.
90-
*
91-
* 'digest' is used when encrypting HMAC Secret Key for storage.
92-
* e.g. 'SHA512' or 'SHA256'. Default value is 'SHA512'.
93-
*
94-
* This is an array of digest values. The keys MUST match and correlate
95-
* to the 'key' array keys.
96-
*
97-
* The valid/current key is identified using 'currentKey'
83+
* Each keyTitle is an associative array containing the required 'key'
84+
* value, and the optional 'driver' and 'digest' values. If the
85+
* 'driver' and 'digest' values are not specified, the default 'driver'
86+
* and 'digest' values will be used.
9887
*
9988
* Old keys will are used to decrypt existing Secret Keys. It is encouraged
10089
* to run 'php spark shield:hmac reencrypt' to update existing Secret
10190
* Key encryptions.
10291
*
10392
* @see https://codeigniter.com/user_guide/libraries/encryption.html
93+
*
94+
* @var array|string
10495
*/
105-
public array $hmacEncryption = [
106-
'key' => ['k1' => ''],
107-
'driver' => ['k1' => 'OpenSSL'],
108-
'digest' => ['k1' => 'SHA512'],
109-
'currentKey' => 'k1',
96+
public $hmacEncryptionKeys = [
97+
'k1' => [
98+
'key' => '',
99+
],
110100
];
101+
102+
/**
103+
* --------------------------------------------------------------------
104+
* HMAC Current Encryption Key Selector
105+
* --------------------------------------------------------------------
106+
* This specifies which of the encryption keys should be used.
107+
*/
108+
public string $hmacEncryptionCurrentKey = 'k1';
109+
110+
/**
111+
* --------------------------------------------------------------------
112+
* HMAC Encryption Key Driver
113+
* --------------------------------------------------------------------
114+
* This specifies which of the encryption drivers should be used.
115+
*
116+
* Available drivers:
117+
* - OpenSSL
118+
* - Sodium
119+
*/
120+
public string $hmacEncryptionDefaultDriver = 'OpenSSL';
121+
122+
/**
123+
* --------------------------------------------------------------------
124+
* HMAC Encryption Key Driver
125+
* --------------------------------------------------------------------
126+
* THis specifies the type of encryption to be used.
127+
* e.g. 'SHA512' or 'SHA256'.
128+
*/
129+
public string $hmacEncryptionDefaultDigest = 'SHA512';
111130
}

src/Config/BaseAuthToken.php

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88

99
class BaseAuthToken extends BaseConfig
1010
{
11-
public array $hmacEncryption;
11+
/**
12+
* List of HMAC Encryption Keys
13+
*
14+
* @var array|string
15+
*/
16+
public $hmacEncryptionKeys;
1217

1318
/**
1419
* AuthToken Config Constructor
@@ -17,18 +22,10 @@ public function __construct()
1722
{
1823
parent::__construct();
1924

20-
$overwriteHmacEncryptionFields = [
21-
'key',
22-
'driver',
23-
'digest',
24-
];
25-
26-
foreach ($overwriteHmacEncryptionFields as $fieldName) {
27-
if (is_string($this->hmacEncryption[$fieldName])) {
28-
$array = json_decode($this->hmacEncryption[$fieldName], true);
29-
if (is_array($array)) {
30-
$this->hmacEncryption[$fieldName] = $array;
31-
}
25+
if (is_string($this->hmacEncryptionKeys)) {
26+
$array = json_decode($this->hmacEncryptionKeys, true);
27+
if (is_array($array)) {
28+
$this->hmacEncryptionKeys = $array;
3229
}
3330
}
3431
}
@@ -43,9 +40,7 @@ public function __construct()
4340
protected function initEnvValue(&$property, string $name, string $prefix, string $shortPrefix): void
4441
{
4542
switch ($name) {
46-
case 'hmacEncryption.key':
47-
case 'hmacEncryption.driver':
48-
case 'hmacEncryption.digest':
43+
case 'hmacEncryptionKeys':
4944
// if attempting to set property from ENV, first set to empty string
5045
if ($this->getEnvValue($name, $prefix, $shortPrefix) !== null) {
5146
$property = '';

tests/Commands/HmacTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public function testReEncrypt(): void
9393
/** @var AuthToken $config */
9494
$config = config('AuthToken');
9595

96-
$config->hmacEncryption['currentKey'] = 'k2';
96+
$config->hmacEncryptionCurrentKey = 'k2';
9797

9898
// new key generated with updated encryption
9999
$token2 = $user->generateHmacToken('bar');

0 commit comments

Comments
 (0)