This is not a duplicate, I'm asking which method is better.
I generate an encoded argon2 hash string, so it'll be stored in database to verify login passwords.
Saved encoded hash has salt of length 16 bytes and tag with length of 32 bytes. I need to derive second different key from the saved key using two parameters:
- User password
- Already existing saved hash
Methods
I have an idea how to do it, but I'm not sure how secure it'll be. I don't want to derive a double length hash and use first half to store in database and second to encryption. Methods:
- Take already existing salt of saved hash
- Generate 64 byte tag and take the second half (skip 32 bytes)
- stored hash will be only with a derived key length 32 bytes and NOT TRUNCATED, when verification program will generate anthoner longer (64 byte) tag and take the second half for encryption.
- I would like to use this method cause it doesn't need two different salts, but is it secure? I don't know how to explain it, so example is on the bottom.
- Generate two different different salts and use one to derive tag for authentication and from second salt derive key for encryption.
- Is Argon2id vulnerable to related-key attack?
Method 1 explaination
User enter a password into a textbox "test" and press button for Registration
- A hash of password is created with a random salt (16 bytes) and 32 byte tag
$argon2id$v=19$m=16,t=2,p=1$SXRkQkVmdGNEMkpMdVEzSg$E015KNeeAHdB0XViXANRjVQN+fKZjWxJbGaGq6CI7/A
To derive encryption key
- Take the same password, same parameters and same salt
- Derive 64 bytes with the same parameters (so it'll be
$argon2id$v=19$m=16,t=2,p=1$SXRkQkVmdGNEMkpMdVEzSg$H+6e3H9iFaRr4+lW/uAicAgb6y8LtSKn0DymU0/0/wnbsEOHQfHSYr9C1lDQmv1UfzyJzOShVKvJm17h6Hcr7Q
)
- Second half (skip 32 bytes and take other 32) will be the encryption key
bsEOHQfHSYr9C1lDQmv1UfzyJzOShVKvJm17h6Hcr7Q
will be the encryption key
I'll not generate first 64 bytes and save only first 32 on user registration, I only generate 32 bytes and on verification 2 times more, so 64 bytes - and I'll take next 32 bytes for encryption.
Shortly, on registration will be generated a 32 byte tag. When loginning and deriving an encryption key, program will take stored hash and it's parameters (TimeCost, Parallelism, MemoryCost, Salt) and create a 64 byte tag from the same password. Second 32 bytes will be the encryption key.
I short: Are both methods secure? Which is better? I think first one is better.
Please note I use Argon2id, thank you. Also I know I cannot have more than 512bit security from Argon2 due to a Blake2 hash length.