php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #75388 Argon2: Add secret/key
Submitted: 2017-10-16 12:38 UTC Modified: 2019-03-30 20:27 UTC
Votes:9
Avg. Score:4.6 ± 0.7
Reproduced:8 of 8 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: phpdoc at mail dot my1 dot info Assigned:
Status: Open Package: *Encryption and hash functions
PHP Version: Next Minor Version OS: Win8.1 x64
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: phpdoc at mail dot my1 dot info
New email:
PHP Version: OS:

 

 [2017-10-16 12:38 UTC] phpdoc at mail dot my1 dot info
Description:
------------
In the input/output section of the argon2 standard, there is a key/secret value

https://tools.ietf.org/html/draft-irtf-cfrg-argon2-03#page-5

and it is certainly not a bad idea to use that for peppering the passwords for extra security:

https://en.wikipedia.org/wiki/Pepper_(cryptography)


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-10-16 14:03 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2017-10-16 14:03 UTC] requinix@php.net
What are you asking for PHP to do, exactly? And is it something that can/should be easily handled in userland instead?
 [2017-10-17 09:34 UTC] daverandom@php.net
@requinix there is a parameter for argon2i ("Secret value K" in the linked document) which PHP does not expose. It *could* be exposed via a password hash option, however I am not qualified to have an opinion on whether it *should* be.

Notably the $salt option for bcrypt was deprecated in 7 because the idea of the password_hash() API is simplicity and providing secure defaults, I don't know if this may fall into the same category of "things the user should not play with as it may make the resulting hashes less secure".

I think what is being asked for is clear, whether it should be done is for people more qualified than me to discuss. I can't see any record if it being discussed as part of the original proposal. It should probably be brought up on internals.
 [2017-10-17 09:55 UTC] phpdoc at mail dot my1 dot info
@requinix

as daverandom points out, I want to have PHP expose the secret which is a part of argon2.

while while you could work around this by attaching a secret by appending, HMAC, or whatever, you could probably also do argon2 in userland, technically, not that it's a good Idea though and it's nice that we have it in PHP7.2

my point is just if argon2 does have something like this already nicely defined, as part of its own standard, why not use it?

@dave, well the salt is a little bit different than an extra secret.

the salt is most notably a RANDOM piece of data attached to some data before it is thrown into the hash and the salt is essentially visible for everyone who can see thze hash, and is to throw rainbow tables into oblivion. and since a salt is supposed to be random, I think it is not a bad Idea to throw the manual setting of the salt away, because there may certainly people who use the XKCD Random number generator.

a Pepper in contrast is usually a special secret value which is stored not in the database but somewhere else (config file environment, whatever you think is best) and should have a certain complexity to be effective, and its point is to have something that even if an attacker can get the hashes via some database leakages they wont be just getting around and calculating all the passwords, even if these are really ugly ones like 123456 because without the secret, an attacker would be getting nowhere.
 [2017-10-17 16:20 UTC] cmb@php.net
-Status: Feedback +Status: Open -Assigned To: +Assigned To: jedisct1
 [2017-10-17 16:20 UTC] cmb@php.net
Feedback has been provided, so opening again.

Assigning to Frank, since he implemented the argon2 password hashing for PHP,
and apparently doesn't like non-replaceable keys[1]. Besides, using the secret
key doesn't appear to work with argon2*_hash_encoded().

[1] <https://github.com/P-H-C/phc-winner-argon2/issues/222>
 [2018-03-29 14:07 UTC] stange at digitalriver dot com
The secret is an important feature with argon2. Other languages expose it.
 [2018-03-29 14:07 UTC] stange at digitalriver dot com
The secret is an important feature with argon2. Other languages expose it.
 [2018-03-29 15:08 UTC] jedisct1@php.net
If you really need this, don't store the salt itself. Generate and store a random `s`, and use `prf(k, s)` as the salt. This is equivalent to adding a secret key to the initial Argon2 state.

A major drawback is the fact that keys cannot be rotated.

A way better approach is to encrypt the hashes. You may also want to add an authentication tag that includes the salt and parameters, to prevent resources starvation if the parameters get modified while still allowing parameter updates.

Authenticated encryption is beyond the scope of a password hashing function. Combining both in a simple way is an API's responsibility.

libsodium 2.x will use the libhydrogen API, but the password hashing API might be backported to the 1.x branch: https://github.com/jedisct1/libhydrogen/wiki/Password-hashing
 [2018-06-16 16:22 UTC] phpdoc at mail dot my1 dot info
@jedisct1
last time I checked, the ability of using arbitrary salts wasnt available for 
PASSWORD_ARGON2I and only for PASSWORD_BCRYPT and even that is deprecated.

and as stange already says it is exposed by other languages and on top of it, it is a part of argon.

why should one go with playing on the salt using a pseudorandom function with both a self made salt and a secret if argon can accept secrets by itself and just use that?

also it's probably more secure than a self-built workaround anyway.
 [2019-03-28 19:50 UTC] davidapgilman at gmail dot com
I concur with the OP - the best way to use a pepper with Argon2 is to use the built in "secret" parameter. There are workarounds as suggested, but the most elegant, audited, and cryptographically secure method is to use the built-in secret parameter as designed.

I understand if there are higher priority PRs, but it's negligent and ignorant to choose to leave off a built-in security feature of the PHC winner. You're encouraging developers to roll their own encryption at worst, and forcing them to choose between a number of non-intuitive workarounds at best. I'd like to re-request this feature.
 [2019-03-28 19:58 UTC] jedisct1@php.net
Halite is very simple to use and does password hashing+encryption:

https://github.com/paragonie/halite/blob/master/doc/Classes/Password.md
 [2019-03-29 16:39 UTC] phpdoc at mail dot my1 dot info
@jedisct1 but isnt that basically also just the makers of that package making their own crypto? I mean encrypting the hash shouldnt be too crazy but in the end it's just a workaround, when instead argon has a way to insert a secret.
 [2019-03-30 19:51 UTC] jedisct1@php.net
All Argon2 parameters get mixed the same way. You can add 3 extra passwords, 2 contexts and 5 more peppers with no changes to the design.

The pepper was documented to improve interoperability between implementations willing to use this, but there is nothing special about the pepper/secret. The reference argon2 tool doesn't support peppers.

The value of a pepper is debatable, especially since encrypting hashes is better both from an operational and a security perspective. If the pepper is leaked, you need to reset the passwords of your entire user base.

The importance of encryption (including salt encryption) was pointed out and discussed by Yescrypt's author after the competition was over.

libsodium does not and will not support peppers. PHP wrappers cannot expose a parameter that doesn't exist.
 [2019-03-30 20:17 UTC] phpdoc at mail dot my1 dot info
@jedisct1

okay let me say a few things:

1) I am NOT mainly talking about libsodium, but about password_hash, which iirc didnt rely on Sodium for hashing.

2) while the reference EXECUTABLE doesnt have the secret/pepper parameter, I want to quote the site of the ref implementation:
https://github.com/P-H-C/phc-winner-argon2
"libargon2 provides an API to both low-level and high-level functions for using Argon2
[...]
The secret parameter, which is used for keyed hashing. This allows a secret key to be input at hashing time (from some external location) and be folded into the value of the hash. This means that even if your salts and hashes are compromized, an attacker cannot brute-force to find the password without the key."

and as far as I am aware password_hash does use libargon2, so it should be possible to add the parameters.

3) while encryption MIGHT be adecent workaround when a proper pepper system is not available, one might wanna note that if someone knew the key they could go and decrypt the hashes and if for some reason the randomness for the salts was screwed (let me remind you that things like debian weak keys happen) one could rainbow table the fun once and have the hashes of anyone who got the key, but with a properly built-in pepper you can't just restore the "normal" salted hash from the end result.

also when re-keying an attacker who got access to the key multiple times they could see whether a target changed their password, which would obviously not happen when playing pepper games.

to top it off when the pepper leaks (no matter whether in-hash or encryption-style) it might (depending on the application) to force the users to change their passwords anyway and if you would just re-encrypt the same old passwords you could also just ask the users to login which would allow to re-hash the passwords without having to reset them.

I personally think both ways have their merits and there isnt too much against giving this to the users.
 [2019-03-30 20:27 UTC] jedisct1@php.net
-Status: Assigned +Status: Open -Assigned To: jedisct1 +Assigned To:
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 09:01:30 2024 UTC