Skip to content

Commit 30a1c56

Browse files
committed
Added AlgorithmEnum and deprecated constants in HashAlgorithm
1 parent 6158336 commit 30a1c56

File tree

12 files changed

+144
-130
lines changed

12 files changed

+144
-130
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Released Notes
22

3+
## v3.1.3 - (2024-08-25)
4+
5+
### Added
6+
7+
- Added `AlgorithmEnum` enum
8+
9+
### Changed
10+
11+
- Changed default cost for bcrypt to 12
12+
- Changed constants in `HashAlgorithm` to deprecated
13+
14+
-----------------------------------------------------------
15+
316
## v3.1.2 - (2024-03-11)
417

518
### Fixed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2022 Brenno Duarte de Lima
3+
Copyright (c) 2024 Brenno Duarte de Lima
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ SecurePassword is a PHP component for creating strong passwords using modern enc
44

55
## Why use this component?
66

7-
Unlike just using `password_hash`, SecurePassword adds a secret entry (commonly called a pepper) to make it difficult to break the generated hash.
7+
Unlike just using `password_hash` or `password_verify`, SecurePassword adds a secret entry (commonly called a pepper) to make it difficult to break the generated hash.
88

99
## Requirements
1010

@@ -35,11 +35,11 @@ var_dump($hash);
3535
You can change encryption settings without using the methods that will be listed below. To do this, enter the following code in the constructor:
3636

3737
```php
38-
use SecurePassword\HashAlgorithm;
38+
use SecurePassword\AlgorithmEnum;
3939

4040
$config = [
41-
'algo' => HashAlgorithm::DEFAULT,
42-
'cost' => 10,
41+
'algo' => AlgorithmEnum::DEFAULT,
42+
'cost' => 12,
4343
'memory_cost' => PASSWORD_ARGON2_DEFAULT_MEMORY_COST,
4444
'time_cost' => PASSWORD_ARGON2_DEFAULT_TIME_COST,
4545
'threads' => PASSWORD_ARGON2_DEFAULT_THREADS
@@ -134,25 +134,24 @@ var_dump($res);
134134

135135
If the encryption type has been changed, you can generate a new hash with the new encryption. The `needsHash()` method checks whether the reported hash needs to be regenerated. Otherwise, it will return `false`.
136136

137+
**Example 1**
138+
137139
```php
138-
/**
139-
* EXAMPLE 1
140-
*/
141140
$password = new SecurePassword();
142141
$hash = $password->useArgon2()->createHash('my_password')->getHash();
143142
$needs = $password->useDefault()->needsRehash('my_password', $hash);
144143

145144
/** Return string */
146145
var_dump($needs);
146+
```
147147

148-
/**
149-
* EXAMPLE 2
150-
*/
148+
**Example 2**
151149

150+
```php
152151
$hash = $password->createHash('my_password')->getHash();
153152

154153
$password = new SecurePassword([
155-
'algo' => HashAlgorithm::BCRYPT
154+
'algo' => AlgorithmEnum::BCRYPT
156155
]);
157156
$needs = $password->needsRehash('my_password', $hash);
158157

@@ -167,15 +166,15 @@ var_dump($needs);
167166
Add options in the `useDefault`, `useBcrypt` and `useArgon2` methods.
168167

169168
- useDefault: default options, use an array.
170-
- useBcrypt: you can change `$cost`. The default is `10`.
169+
- useBcrypt: you can change `$cost`. The default is `12`.
171170
- useArgon2: you can change `$memory_cost`, `$time_cost` and `$threads`. The default is the constants `PASSWORD_ARGON2_DEFAULT_MEMORY_COST`, `PASSWORD_ARGON2_DEFAULT_TIME_COST` and `PASSWORD_ARGON2_DEFAULT_THREADS`.
172171

173172
```php
174173
# standard encryption
175174
$hash = $password->useDefault([])->createHash('my_password');
176175

177176
# Bcrypt encryption
178-
$hash = $password->useBcrypt(10)->createHash('my_password');
177+
$hash = $password->useBcrypt(12)->createHash('my_password');
179178

180179
# Argon2 encryption
181180
$hash = $password->useArgon2(false, PASSWORD_ARGON2_DEFAULT_MEMORY_COST, PASSWORD_ARGON2_DEFAULT_TIME_COST, PASSWORD_ARGON2_DEFAULT_THREADS)->createHash('my_password');
@@ -197,7 +196,6 @@ $encryption = new Encryption('your-key');
197196

198197
//Encrypt the message
199198
$encrypt = $encryption->encrypt("This is a text");
200-
201199
echo $encrypt;
202200
```
203201

@@ -208,17 +206,19 @@ $encryption = new Encryption('your-key');
208206

209207
//Decrypt the message
210208
$decrypt = $encryption->decrypt($encrypt);
211-
212209
echo $decrypt;
213210
```
214211

215212
You can pass supported adapter to class like:
216213

217-
Use of OpenSSL
214+
**Use of OpenSSL**
215+
218216
```php
219217
$encryption = new Encryption(new OpenSslEncryption('your-key'));
220218
```
221-
Use of Sodium
219+
220+
**Use of Sodium**
221+
222222
```php
223223
$encryption = new Encryption(new SodiumEncryption('your-key'));
224224
```

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,8 @@
1818
"psr-4": {
1919
"SecurePassword\\": "src/"
2020
}
21+
},
22+
"suggest": {
23+
"ext-libsodium": "To use Sodium encryption"
2124
}
2225
}

phpunit.xml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" colors="true" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.4/phpunit.xsd" cacheDirectory=".phpunit.cache">
2+
<phpunit
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
stopOnFailure="false"
7+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.0/phpunit.xsd"
8+
cacheDirectory=".phpunit.cache"
9+
displayDetailsOnTestsThatTriggerDeprecations="true"
10+
displayDetailsOnTestsThatTriggerErrors="true"
11+
displayDetailsOnTestsThatTriggerNotices="true"
12+
displayDetailsOnTestsThatTriggerWarnings="true">
313
<testsuites>
4-
<testsuite name="Password Test Suite">
14+
<testsuite name="Password test suite">
515
<directory>tests</directory>
616
</testsuite>
717
</testsuites>
8-
</phpunit>
18+
</phpunit>

src/AlgorithmEnum.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace SecurePassword;
4+
5+
enum AlgorithmEnum: string
6+
{
7+
case DEFAULT = "default";
8+
case BCRYPT = PASSWORD_BCRYPT;
9+
case ARGON2I = PASSWORD_ARGON2I;
10+
case ARGON2ID = PASSWORD_ARGON2ID;
11+
}

src/Encrypt/Adapter/OpenSslEncryption.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,7 @@ class OpenSslEncryption implements AbstractAdapterInterface
3434
*/
3535
public function __construct(string $key)
3636
{
37-
if ($key === '') {
38-
throw new \InvalidArgumentException('The key should not be empty string.');
39-
}
40-
37+
if ($key === '') throw new \InvalidArgumentException('The key should not be empty string.');
4138
$this->iv = openssl_random_pseudo_bytes($this->ivBytes($this->cipher));
4239
$this->key = hash('sha512', $key);
4340
}
@@ -47,25 +44,26 @@ public function __construct(string $key)
4744
*
4845
* @param mixed $data => data to be encrypted
4946
*
50-
* @return token
47+
* @return mixed
5148
*/
5249
public function encrypt(mixed $data): mixed
5350
{
54-
return base64_encode(openssl_encrypt($data, $this->cipher, $this->key, 0, $this->iv).'&&'.bin2hex($this->iv));
51+
return base64_encode(
52+
openssl_encrypt($data, $this->cipher, $this->key, 0, $this->iv) . '&&' . bin2hex($this->iv)
53+
);
5554
}
5655

5756
/**
5857
* Decrypt the message.
5958
*
6059
* @param mixed $token => encrypted token
6160
62-
* @return mix-data
61+
* @return string|bool
6362
*/
64-
public function decrypt(mixed $token): mixed
63+
public function decrypt(mixed $token): string|bool
6564
{
6665
$token = base64_decode($token);
6766
list($token, $this->iv) = explode('&&', $token);
68-
6967
return openssl_decrypt($token, $this->cipher, $this->key, 0, hex2bin($this->iv));
7068
}
7169

src/Encrypt/Adapter/SodiumEncryption.php

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,10 @@ class SodiumEncryption implements AbstractAdapterInterface
1818
*/
1919
public function __construct(string $key)
2020
{
21-
if ($key === '') {
22-
throw new \InvalidArgumentException('The key should not be empty string.');
23-
}
24-
25-
if (!function_exists('sodium_crypto_secretbox_keygen')) {
21+
if ($key === '') throw new \InvalidArgumentException('The key should not be empty string.');
22+
23+
if (!function_exists('sodium_crypto_secretbox_keygen'))
2624
throw new \Exception('The sodium php extension does not installed or enabled', 500);
27-
}
2825

2926
//should use user define key.
3027
$this->key = substr(hash('sha512', $key), 0, 32);
@@ -40,8 +37,7 @@ public function __construct(string $key)
4037
public function encrypt(mixed $data): mixed
4138
{
4239
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
43-
$token = base64_encode($nonce.sodium_crypto_secretbox($data, $nonce, $this->key).'&&'.$this->key);
44-
40+
$token = base64_encode($nonce . sodium_crypto_secretbox($data, $nonce, $this->key) . '&&' . $this->key);
4541
return $token;
4642
}
4743

@@ -56,25 +52,18 @@ public function decrypt(mixed $token): mixed
5652
{
5753
$decoded = base64_decode($token);
5854
list($decoded, $this->key) = explode('&&', $decoded);
59-
60-
if ($decoded === false) {
61-
throw new \Exception('The decoding failed');
62-
}
55+
if ($decoded === false) throw new \Exception('The decoding failed');
6356

64-
if (mb_strlen($decoded, '8bit') < (SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES)) {
57+
if (
58+
mb_strlen($decoded, '8bit') < (SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES)
59+
) {
6560
throw new \Exception('The token was truncated');
6661
}
6762

6863
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
6964
$ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
70-
71-
$plain = sodium_crypto_secretbox_open($ciphertext,
72-
$nonce, $this->key);
73-
74-
if ($plain === false) {
75-
throw new \Exception('The message was tampered with in transit');
76-
}
77-
65+
$plain = sodium_crypto_secretbox_open($ciphertext, $nonce, $this->key);
66+
if ($plain === false) throw new \Exception('The message was tampered with in transit');
7867
return $plain;
7968
}
8069
}

src/HashAlgorithm.php

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,28 @@
44

55
abstract class HashAlgorithm
66
{
7+
/**
8+
* @deprecated Use `AlgorithmEnum` enum
9+
* @var mixed
10+
*/
711
const DEFAULT = PASSWORD_DEFAULT;
12+
13+
/**
14+
* @deprecated Use `AlgorithmEnum` enum
15+
* @var mixed
16+
*/
817
const BCRYPT = PASSWORD_BCRYPT;
18+
19+
/**
20+
* @deprecated Use `AlgorithmEnum` enum
21+
* @var mixed
22+
*/
923
const ARGON2I = PASSWORD_ARGON2I;
24+
25+
/**
26+
* @deprecated Use `AlgorithmEnum` enum
27+
* @var mixed
28+
*/
1029
const ARGON2ID = PASSWORD_ARGON2ID;
1130

1231
/**
@@ -27,8 +46,7 @@ abstract class HashAlgorithm
2746
public function useDefault(array $options = []): SecurePassword
2847
{
2948
$this->options = $options;
30-
$this->algo = self::DEFAULT;
31-
49+
$this->algo = PASSWORD_DEFAULT;
3250
return $this;
3351
}
3452

@@ -37,11 +55,10 @@ public function useDefault(array $options = []): SecurePassword
3755
*
3856
* @return SecurePassword
3957
*/
40-
public function useBcrypt(int $cost = 10): SecurePassword
58+
public function useBcrypt(int $cost = 12): SecurePassword
4159
{
4260
$this->options['cost'] = $cost;
43-
$this->algo = self::BCRYPT;
44-
61+
$this->algo = AlgorithmEnum::BCRYPT->value;
4562
return $this;
4663
}
4764

@@ -65,12 +82,8 @@ public function useArgon2(
6582
'threads' => $threads
6683
];
6784

68-
$this->algo = self::ARGON2I;
69-
70-
if ($use_argon2d == true) {
71-
$this->algo = self::ARGON2ID;
72-
}
73-
85+
$this->algo = AlgorithmEnum::ARGON2I->value;
86+
if ($use_argon2d == true) $this->algo = AlgorithmEnum::ARGON2ID->value;
7487
return $this;
7588
}
7689
}

src/PepperTrait.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,11 @@ public function setPepper(string $pepper = "default_hash", string $crypt_type =
4343
public function getPepper(): string
4444
{
4545
if ($this->pepper !== '') {
46-
if ($this->crypt_type == 'openssl') {
47-
$encryption = new Encryption(new OpenSslEncryption($this->pepper));
48-
$this->pepper = $encryption->decrypt($this->pepper);
49-
}
46+
if ($this->crypt_type == 'openssl') $adapter = new OpenSslEncryption($this->pepper);
47+
if ($this->crypt_type == 'sodium') $adapter = new SodiumEncryption($this->pepper);
5048

51-
if ($this->crypt_type == 'sodium') {
52-
$encryption = new Encryption(new SodiumEncryption($this->pepper));
53-
$this->pepper = $encryption->decrypt($this->pepper);
54-
}
49+
$encryption = new Encryption($adapter);
50+
$this->pepper = $encryption->decrypt($this->pepper);
5551
}
5652

5753
return $this->pepper;

0 commit comments

Comments
 (0)