samuel-lucas6 / draft-lucas-bkdf

An Internet-Draft for the Balloon Key Derivation Function (BKDF), a memory-hard password hashing and password-based key derivation function.
Other
4 stars 1 forks source link

Support for a pepper #7

Closed samuel-lucas6 closed 2 months ago

samuel-lucas6 commented 8 months ago

A secret key could be supported like in Argon2. However, I'm not convinced this is a good idea because encrypting password hashes is preferable, as explained in the Security Considerations section. Supporting this would suggest otherwise, even though it could be useful for key derivation.

Sc00bz commented 2 months ago

I agree. But you might want to have "extra salts". This is useful for PAKEs where you include the user ID, server ID, OPRF salt (or salt), and local/secret salt (if there is one). This is just to avoid collisions for H(salt || userId || serverId) like H(salt || "user1" || "server") and H(salt || "user" || "1server") etc. It doesn't matter how you do it but the simplest is salt' = H(H(salt) || H(userId) || H(serverId) || ... ).

samuel-lucas6 commented 2 months ago

Could the user not just supply that via the existing salt parameter? They'd obviously have to do proper separation though like encoding the lengths.

Sc00bz commented 2 months ago

Yes, but having it as an option prevents the user of the API from needing to think about encoding lengths or other proper separation methods and maybe messing it up. Also it gives a common implemented method for this.

samuel-lucas6 commented 2 months ago

I hear you. I've not seen any other algorithm do this though. What would the API look like? An array of salts and you append the length of each one?

As mentioned in #14, it will probably be easy to support a pepper once the switch from Hash() to PRF() is made.

Sc00bz commented 2 months ago

C

int balloon_kdf(
    void       *output,   size_t outputSize,
    const void *password, size_t passwordSize,
    const void *salt,     size_t saltSize,
    uint32_t    memory, uint32_t iterations, uint32_t parallelism,
    uint32_t    maxThreads, int wipeMem,
    size_t      numExtraSalts = 0, void **extraSalts = NULL, size_t *extraSaltsSizes = NULL);

C++

int balloon_kdf(
    void *output, size_t outputSize,
    const std:string &password, const std:string &salt,
    uint32_t memory, uint32_t iterations, uint32_t parallelism,
    uint32_t maxThreads, int wipeMem,
    const std:vector<std:string> *extraSalts = NULL);

Go

func balloon_kdf(
    outputSize int,
    password []byte, salt []byte,
    memory int, iterations int, parallelism int,
    maxThreads int, wipeMem int,
    extraSalts [][]byte) (output []byte, err error) {
...
key, _ := balloon_kdf(
    keySize,
    []byte("password"), []byte("salt"),
    memory, iterations, parallelism,
    maxThreads, wipeMem,
    nil)