From ed476a70546698f04e9ff29e7e65edc771291763 Mon Sep 17 00:00:00 2001 From: dehbka Date: Wed, 4 Sep 2024 22:09:47 +0300 Subject: [PATCH 1/5] Add SensitiveParameter to secrets --- src/Crypt.php | 12 ++++++------ src/Mac.php | 4 ++-- src/PasswordHasher.php | 4 ++-- src/TokenMask.php | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Crypt.php b/src/Crypt.php index df4de2f..b23cc95 100644 --- a/src/Crypt.php +++ b/src/Crypt.php @@ -123,7 +123,7 @@ public function withDerivationIterations(int $iterations): self * @see decryptByPassword() * @see encryptByKey() */ - public function encryptByPassword(string $data, string $password): string + public function encryptByPassword(string $data, #[\SensitiveParameter] string $password): string { return $this->encrypt($data, true, $password, ''); } @@ -150,7 +150,7 @@ public function encryptByPassword(string $data, string $password): string * @see decryptByKey() * @see encryptByPassword() */ - public function encryptByKey(string $data, string $inputKey, string $info = ''): string + public function encryptByKey(string $data, #[\SensitiveParameter] string $inputKey, string $info = ''): string { return $this->encrypt($data, false, $inputKey, $info); } @@ -169,7 +169,7 @@ public function encryptByKey(string $data, string $inputKey, string $info = ''): * * @see encryptByPassword() */ - public function decryptByPassword(string $data, string $password): string + public function decryptByPassword(string $data, #[\SensitiveParameter] string $password): string { return $this->decrypt($data, true, $password, ''); } @@ -190,7 +190,7 @@ public function decryptByPassword(string $data, string $password): string * * @see encryptByKey() */ - public function decryptByKey(string $data, string $inputKey, string $info = ''): string + public function decryptByKey(string $data, #[\SensitiveParameter] string $inputKey, string $info = ''): string { return $this->decrypt($data, false, $inputKey, $info); } @@ -211,7 +211,7 @@ public function decryptByKey(string $data, string $inputKey, string $info = ''): * * @see decrypt() */ - private function encrypt(string $data, bool $passwordBased, string $secret, string $info = ''): string + private function encrypt(string $data, bool $passwordBased, #[\SensitiveParameter] string $secret, string $info = ''): string { [$blockSize, $keySize] = self::ALLOWED_CIPHERS[$this->cipher]; @@ -257,7 +257,7 @@ private function encrypt(string $data, bool $passwordBased, string $secret, stri * * @see encrypt() */ - private function decrypt(string $data, bool $passwordBased, string $secret, string $info): string + private function decrypt(string $data, bool $passwordBased, #[\SensitiveParameter] string $secret, string $info): string { [$blockSize, $keySize] = self::ALLOWED_CIPHERS[$this->cipher]; diff --git a/src/Mac.php b/src/Mac.php index 8f511c2..3999ab2 100644 --- a/src/Mac.php +++ b/src/Mac.php @@ -51,7 +51,7 @@ public function __construct(string $algorithm = 'sha256') * @see hkdf() * @see pbkdf2() */ - public function sign(string $data, string $key, bool $rawHash = false): string + public function sign(string $data, #[\SensitiveParameter] string $key, bool $rawHash = false): string { $hash = hash_hmac($this->algorithm, $data, $key, $rawHash); if (!$hash) { @@ -80,7 +80,7 @@ public function sign(string $data, string $key, bool $rawHash = false): string * * @see hash() */ - public function getMessage(string $data, string $key, bool $rawHash = false): string + public function getMessage(string $data, #[\SensitiveParameter] string $key, bool $rawHash = false): string { $test = hash_hmac($this->algorithm, '', '', $rawHash); if (!$test) { diff --git a/src/PasswordHasher.php b/src/PasswordHasher.php index 4ad78d0..7ad462d 100644 --- a/src/PasswordHasher.php +++ b/src/PasswordHasher.php @@ -65,7 +65,7 @@ public function __construct(?string $algorithm = PASSWORD_DEFAULT, array $parame * @psalm-suppress InvalidNullableReturnType * @psalm-suppress NullableReturnStatement */ - public function hash(string $password): string + public function hash(#[\SensitiveParameter] string $password): string { return password_hash($password, $this->algorithm, $this->parameters); } @@ -83,7 +83,7 @@ public function hash(string $password): string * * @see hash() */ - public function validate(string $password, string $hash): bool + public function validate(#[\SensitiveParameter] string $password, string $hash): bool { if ($password === '') { throw new \InvalidArgumentException('Password must be a string and cannot be empty.'); diff --git a/src/TokenMask.php b/src/TokenMask.php index 79d57b6..687ef61 100644 --- a/src/TokenMask.php +++ b/src/TokenMask.php @@ -22,7 +22,7 @@ final class TokenMask * * @return string A masked token. */ - public static function apply(string $token): string + public static function apply(#[\SensitiveParameter] string $token): string { // The number of bytes in a mask is always equal to the number of bytes in a token. /** @psalm-suppress ArgumentTypeCoercion */ @@ -37,7 +37,7 @@ public static function apply(string $token): string * * @return string An unmasked token, or an empty string in case of token format is invalid. */ - public static function remove(string $maskedToken): string + public static function remove(#[\SensitiveParameter] string $maskedToken): string { $decoded = StringHelper::base64UrlDecode($maskedToken); $length = StringHelper::byteLength($decoded) / 2; From e4e2622921778025405605782f90b7f0c86e8c1a Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 25 Feb 2025 15:28:01 +0300 Subject: [PATCH 2/5] fix --- CHANGELOG.md | 2 +- src/Crypt.php | 44 +++++++++++++++++++++++++++++++++++------- src/Mac.php | 15 ++++++++++++-- src/PasswordHasher.php | 13 +++++++++++-- src/TokenMask.php | 11 +++++++++-- 5 files changed, 71 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61fece0..0b881af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 1.0.3 under development -- no changes in this release. +- Enh #62: Use `SensitiveParameter` attribute to mark sensitive parameters (@dehbka, @vjik) ## 1.0.2 March 18, 2024 diff --git a/src/Crypt.php b/src/Crypt.php index b23cc95..d119466 100644 --- a/src/Crypt.php +++ b/src/Crypt.php @@ -4,6 +4,7 @@ namespace Yiisoft\Security; +use SensitiveParameter; use Yiisoft\Strings\StringHelper; final class Crypt @@ -123,8 +124,11 @@ public function withDerivationIterations(int $iterations): self * @see decryptByPassword() * @see encryptByKey() */ - public function encryptByPassword(string $data, #[\SensitiveParameter] string $password): string - { + public function encryptByPassword( + string $data, + #[SensitiveParameter] + string $password + ): string { return $this->encrypt($data, true, $password, ''); } @@ -150,7 +154,12 @@ public function encryptByPassword(string $data, #[\SensitiveParameter] string $p * @see decryptByKey() * @see encryptByPassword() */ - public function encryptByKey(string $data, #[\SensitiveParameter] string $inputKey, string $info = ''): string + public function encryptByKey( + string $data, + #[SensitiveParameter] + string $inputKey, + string $info = '' + ): string { return $this->encrypt($data, false, $inputKey, $info); } @@ -169,7 +178,11 @@ public function encryptByKey(string $data, #[\SensitiveParameter] string $inputK * * @see encryptByPassword() */ - public function decryptByPassword(string $data, #[\SensitiveParameter] string $password): string + public function decryptByPassword( + string $data, + #[SensitiveParameter] + string $password + ): string { return $this->decrypt($data, true, $password, ''); } @@ -190,7 +203,12 @@ public function decryptByPassword(string $data, #[\SensitiveParameter] string $p * * @see encryptByKey() */ - public function decryptByKey(string $data, #[\SensitiveParameter] string $inputKey, string $info = ''): string + public function decryptByKey( + string $data, + #[SensitiveParameter] + string $inputKey, + string $info = '' + ): string { return $this->decrypt($data, false, $inputKey, $info); } @@ -211,7 +229,13 @@ public function decryptByKey(string $data, #[\SensitiveParameter] string $inputK * * @see decrypt() */ - private function encrypt(string $data, bool $passwordBased, #[\SensitiveParameter] string $secret, string $info = ''): string + private function encrypt( + string $data, + bool $passwordBased, + #[SensitiveParameter] + string $secret, + string $info = '' + ): string { [$blockSize, $keySize] = self::ALLOWED_CIPHERS[$this->cipher]; @@ -257,7 +281,13 @@ private function encrypt(string $data, bool $passwordBased, #[\SensitiveParamete * * @see encrypt() */ - private function decrypt(string $data, bool $passwordBased, #[\SensitiveParameter] string $secret, string $info): string + private function decrypt( + string $data, + bool $passwordBased, + #[SensitiveParameter] + string $secret, + string $info + ): string { [$blockSize, $keySize] = self::ALLOWED_CIPHERS[$this->cipher]; diff --git a/src/Mac.php b/src/Mac.php index 3999ab2..2c5c973 100644 --- a/src/Mac.php +++ b/src/Mac.php @@ -4,6 +4,7 @@ namespace Yiisoft\Security; +use SensitiveParameter; use Yiisoft\Strings\StringHelper; /** @@ -51,7 +52,12 @@ public function __construct(string $algorithm = 'sha256') * @see hkdf() * @see pbkdf2() */ - public function sign(string $data, #[\SensitiveParameter] string $key, bool $rawHash = false): string + public function sign( + string $data, + #[SensitiveParameter] + string $key, + bool $rawHash = false + ): string { $hash = hash_hmac($this->algorithm, $data, $key, $rawHash); if (!$hash) { @@ -80,7 +86,12 @@ public function sign(string $data, #[\SensitiveParameter] string $key, bool $raw * * @see hash() */ - public function getMessage(string $data, #[\SensitiveParameter] string $key, bool $rawHash = false): string + public function getMessage( + string $data, + #[SensitiveParameter] + string $key, + bool $rawHash = false + ): string { $test = hash_hmac($this->algorithm, '', '', $rawHash); if (!$test) { diff --git a/src/PasswordHasher.php b/src/PasswordHasher.php index 7ad462d..c3ae362 100644 --- a/src/PasswordHasher.php +++ b/src/PasswordHasher.php @@ -4,6 +4,8 @@ namespace Yiisoft\Security; +use SensitiveParameter; + /** * PasswordHasher allows generating password hash and verifying passwords against a hash. */ @@ -65,7 +67,10 @@ public function __construct(?string $algorithm = PASSWORD_DEFAULT, array $parame * @psalm-suppress InvalidNullableReturnType * @psalm-suppress NullableReturnStatement */ - public function hash(#[\SensitiveParameter] string $password): string + public function hash( + #[SensitiveParameter] + string $password + ): string { return password_hash($password, $this->algorithm, $this->parameters); } @@ -83,7 +88,11 @@ public function hash(#[\SensitiveParameter] string $password): string * * @see hash() */ - public function validate(#[\SensitiveParameter] string $password, string $hash): bool + public function validate( + #[SensitiveParameter] + string $password, + string $hash + ): bool { if ($password === '') { throw new \InvalidArgumentException('Password must be a string and cannot be empty.'); diff --git a/src/TokenMask.php b/src/TokenMask.php index 687ef61..3596d49 100644 --- a/src/TokenMask.php +++ b/src/TokenMask.php @@ -4,6 +4,7 @@ namespace Yiisoft\Security; +use SensitiveParameter; use Yiisoft\Strings\StringHelper; /** @@ -22,7 +23,10 @@ final class TokenMask * * @return string A masked token. */ - public static function apply(#[\SensitiveParameter] string $token): string + public static function apply( + #[SensitiveParameter] + string $token + ): string { // The number of bytes in a mask is always equal to the number of bytes in a token. /** @psalm-suppress ArgumentTypeCoercion */ @@ -37,7 +41,10 @@ public static function apply(#[\SensitiveParameter] string $token): string * * @return string An unmasked token, or an empty string in case of token format is invalid. */ - public static function remove(#[\SensitiveParameter] string $maskedToken): string + public static function remove( + #[SensitiveParameter] + string $maskedToken + ): string { $decoded = StringHelper::base64UrlDecode($maskedToken); $length = StringHelper::byteLength($decoded) / 2; From afb41300e13f94f99c958e5940bf1f51b0c87482 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 25 Feb 2025 15:30:40 +0300 Subject: [PATCH 3/5] fix cs --- src/Crypt.php | 15 +++++---------- src/Mac.php | 6 ++---- src/PasswordHasher.php | 3 +-- src/TokenMask.php | 6 ++---- 4 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/Crypt.php b/src/Crypt.php index d119466..d11972e 100644 --- a/src/Crypt.php +++ b/src/Crypt.php @@ -159,8 +159,7 @@ public function encryptByKey( #[SensitiveParameter] string $inputKey, string $info = '' - ): string - { + ): string { return $this->encrypt($data, false, $inputKey, $info); } @@ -182,8 +181,7 @@ public function decryptByPassword( string $data, #[SensitiveParameter] string $password - ): string - { + ): string { return $this->decrypt($data, true, $password, ''); } @@ -208,8 +206,7 @@ public function decryptByKey( #[SensitiveParameter] string $inputKey, string $info = '' - ): string - { + ): string { return $this->decrypt($data, false, $inputKey, $info); } @@ -235,8 +232,7 @@ private function encrypt( #[SensitiveParameter] string $secret, string $info = '' - ): string - { + ): string { [$blockSize, $keySize] = self::ALLOWED_CIPHERS[$this->cipher]; $keySalt = random_bytes($keySize); @@ -287,8 +283,7 @@ private function decrypt( #[SensitiveParameter] string $secret, string $info - ): string - { + ): string { [$blockSize, $keySize] = self::ALLOWED_CIPHERS[$this->cipher]; $keySalt = StringHelper::byteSubstring($data, 0, $keySize); diff --git a/src/Mac.php b/src/Mac.php index 2c5c973..4c35ab8 100644 --- a/src/Mac.php +++ b/src/Mac.php @@ -57,8 +57,7 @@ public function sign( #[SensitiveParameter] string $key, bool $rawHash = false - ): string - { + ): string { $hash = hash_hmac($this->algorithm, $data, $key, $rawHash); if (!$hash) { throw new \RuntimeException("Failed to generate HMAC with hash algorithm: {$this->algorithm}."); @@ -91,8 +90,7 @@ public function getMessage( #[SensitiveParameter] string $key, bool $rawHash = false - ): string - { + ): string { $test = hash_hmac($this->algorithm, '', '', $rawHash); if (!$test) { throw new \RuntimeException("Failed to generate HMAC with hash algorithm: {$this->algorithm}."); diff --git a/src/PasswordHasher.php b/src/PasswordHasher.php index c3ae362..3daa174 100644 --- a/src/PasswordHasher.php +++ b/src/PasswordHasher.php @@ -70,8 +70,7 @@ public function __construct(?string $algorithm = PASSWORD_DEFAULT, array $parame public function hash( #[SensitiveParameter] string $password - ): string - { + ): string { return password_hash($password, $this->algorithm, $this->parameters); } diff --git a/src/TokenMask.php b/src/TokenMask.php index 3596d49..39aa776 100644 --- a/src/TokenMask.php +++ b/src/TokenMask.php @@ -26,8 +26,7 @@ final class TokenMask public static function apply( #[SensitiveParameter] string $token - ): string - { + ): string { // The number of bytes in a mask is always equal to the number of bytes in a token. /** @psalm-suppress ArgumentTypeCoercion */ $mask = random_bytes(StringHelper::byteLength($token)); @@ -44,8 +43,7 @@ public static function apply( public static function remove( #[SensitiveParameter] string $maskedToken - ): string - { + ): string { $decoded = StringHelper::base64UrlDecode($maskedToken); $length = StringHelper::byteLength($decoded) / 2; // Check if the masked token has an even length. From 934fd324d66449bd151983600cdfc2dcd40368be Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 25 Feb 2025 15:31:41 +0300 Subject: [PATCH 4/5] cs --- src/PasswordHasher.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PasswordHasher.php b/src/PasswordHasher.php index 3daa174..1733484 100644 --- a/src/PasswordHasher.php +++ b/src/PasswordHasher.php @@ -91,8 +91,7 @@ public function validate( #[SensitiveParameter] string $password, string $hash - ): bool - { + ): bool { if ($password === '') { throw new \InvalidArgumentException('Password must be a string and cannot be empty.'); } From f98ba54e9c6b60e4b097ffebad3743174dbbb8c0 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 25 Feb 2025 17:37:17 +0300 Subject: [PATCH 5/5] improve --- src/PasswordHasher.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PasswordHasher.php b/src/PasswordHasher.php index 1733484..d8175c0 100644 --- a/src/PasswordHasher.php +++ b/src/PasswordHasher.php @@ -90,6 +90,7 @@ public function hash( public function validate( #[SensitiveParameter] string $password, + #[SensitiveParameter] string $hash ): bool { if ($password === '') {