Skip to content

Commit 0acff4b

Browse files
committed
Rework of encryption methods
Typo fixes in documentation
1 parent 85b8db6 commit 0acff4b

4 files changed

Lines changed: 54 additions & 18 deletions

File tree

UPGRADING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ 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 `$hmacEncryptionKey`. This should be set using .env and/or system
56+
You will need to update and set the encryption key `$hmacEncryptionKey`. This should be set using **.env** and/or system
5757
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.

docs/guides/api_hmac_keys.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Tokens are issued with the `generateHmacToken()` method on the user. This return
1818
`CodeIgniter\Shield\Entities\AccessToken` instance. The `AccessToken` object returned will include a `secret` field
1919
which will be the '**key**' and a `rawSecretKey` field that will be the '**secretKey**'. You should display the
2020
'**secretKey**' to your user immediately, so they have a chance to copy it somewhere safe, as this is the only time
21-
you can reveal this key. The '**key**' and '**sharedKey**' are saved to the database. The '**secretKey**' is stored
21+
you can reveal this key. The '**key**' and '**secretKey**' are saved to the database. The '**secretKey**' is stored
2222
encrypted.
2323

2424
The `generateHmacToken()` method requires a name for the token. These are free strings and are often used to identify
@@ -91,7 +91,7 @@ $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-
`$hmacEncryptionKey` in **app/Config/AuthToken.php**. This should be set using .env and/or system environment variables.
94+
`$hmacEncryptionKey` in **app/Config/AuthToken.php**. This should be set using **.env** and/or system environment variables.
9595
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.

src/Authentication/HMAC/HmacEncrypter.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,30 +49,33 @@ public function __construct()
4949
/**
5050
* Decrypt
5151
*
52-
* @param string $base64String Encrypted string in base64 format
52+
* @param string $encString Encrypted string
5353
*
5454
* @return string Raw decrypted string
5555
*
5656
* @throws EncryptionException
5757
*/
58-
public function decrypt(string $base64String): string
58+
public function decrypt(string $encString): string
5959
{
60-
return $this->encrypter->decrypt(base64_decode($base64String, true));
60+
// Removes `$b6$` for base64 format.
61+
$encString = substr($encString, 4);
62+
63+
return $this->encrypter->decrypt(base64_decode($encString, true));
6164
}
6265

6366
/**
6467
* Encrypt
6568
*
6669
* @param string $rawString Raw string to encrypt
6770
*
68-
* @return string Encrypted string in base64 format
71+
* @return string Encrypted string
6972
*
7073
* @throws EncryptionException
7174
* @throws RuntimeException
7275
*/
7376
public function encrypt(string $rawString): string
7477
{
75-
$encryptedString = base64_encode($this->encrypter->encrypt($rawString));
78+
$encryptedString = '$b6$' . base64_encode($this->encrypter->encrypt($rawString));
7679

7780
if (strlen($encryptedString) > $this->authConfig->secret2StorageLimit) {
7881
throw new RuntimeException('Encrypted key too long. Unable to store value.');
@@ -81,6 +84,14 @@ public function encrypt(string $rawString): string
8184
return $encryptedString;
8285
}
8386

87+
/**
88+
* Check if the string already encrypted
89+
*/
90+
public function isEncrypted(string $string): bool
91+
{
92+
return str_starts_with($string, '$b6$');
93+
}
94+
8495
/**
8596
* Generate Key
8697
*

src/Commands/Hmac.php

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use CodeIgniter\Shield\Authentication\HMAC\HmacEncrypter;
88
use CodeIgniter\Shield\Commands\Exceptions\BadInputException;
9+
use CodeIgniter\Shield\Exceptions\RuntimeException;
910
use CodeIgniter\Shield\Models\UserIdentityModel;
1011
use Exception;
1112
use ReflectionException;
@@ -99,15 +100,29 @@ public function run(array $params): int
99100
*/
100101
public function encrypt(): void
101102
{
102-
$uIdModel = new UserIdentityModel();
103-
$encrypter = $this->encrypter;
103+
$uIdModel = new UserIdentityModel();
104+
$uIdModelSub = new UserIdentityModel(); // For saving.
105+
$encrypter = $this->encrypter;
104106

105-
$uIdModel->where('type', 'hmac_sha256')->chunk(
107+
$that = $this;
108+
109+
$uIdModel->where('type', 'hmac_sha256')->orderBy('id')->chunk(
106110
100,
107-
static function ($identity) use ($uIdModel, $encrypter): void {
108-
$identity->secret2 = $encrypter->encrypt($identity->secret2);
111+
static function ($identity) use ($uIdModelSub, $encrypter, $that): void {
112+
if ($encrypter->isEncrypted($identity->secret2)) {
113+
$that->write('id: ' . $identity->id . ', already encrypted, skipped.');
114+
115+
return;
116+
}
117+
118+
try {
119+
$identity->secret2 = $encrypter->encrypt($identity->secret2);
120+
$uIdModelSub->save($identity);
109121

110-
$uIdModel->save($identity);
122+
$that->write('id: ' . $identity->id . ', encrypted.');
123+
} catch (RuntimeException $e) {
124+
$that->error('id: ' . $identity->id . ', ' . $e->getMessage());
125+
}
111126
}
112127
);
113128
}
@@ -119,15 +134,25 @@ static function ($identity) use ($uIdModel, $encrypter): void {
119134
*/
120135
public function decrypt(): void
121136
{
122-
$uIdModel = new UserIdentityModel();
123-
$encrypter = $this->encrypter;
137+
$uIdModel = new UserIdentityModel();
138+
$uIdModelSub = new UserIdentityModel(); // For saving.
139+
$encrypter = $this->encrypter;
140+
141+
$that = $this;
124142

125143
$uIdModel->where('type', 'hmac_sha256')->chunk(
126144
100,
127-
static function ($identity) use ($uIdModel, $encrypter): void {
145+
static function ($identity) use ($uIdModelSub, $encrypter, $that): void {
146+
if (! $encrypter->isEncrypted($identity->secret2)) {
147+
$that->write('id: ' . $identity->id . ', not encrypted, skipped.');
148+
149+
return;
150+
}
151+
128152
$identity->secret2 = $encrypter->decrypt($identity->secret2);
153+
$uIdModelSub->save($identity);
129154

130-
$uIdModel->save($identity);
155+
$that->write('id: ' . $identity->id . ', decrypted.');
131156
}
132157
);
133158
}

0 commit comments

Comments
 (0)