I'd like to authenticate my users without storing their password, even in a derived form with scrypt/pbkdf or other derivation methods.
I'm exploring the idea of encrypting a random payload with AES GCM, and storing it alongside its IV and tag. Then, authentication would simply be a matter of decrypting that payload with the provided password. I'm counting on the fact that the GCM algorithm will fail to decrypt/authenticate the data if the password is wrong.
When creating a new user, I would generate a key based on the provided password, a random IV and a random payload.
# Password is provided by the user
password := get_password_from_user()
iv := generate_random_iv()
payload := generate_random_payload()
encrypted_payload, tag = encrypt('aes-256-gcm', password, iv, payload)
store_authentication_info(iv, tag, encrypted_payload)
The authentication process would simply decrypt the payload, checking the tag.
# Password is provided by the user
password := get_password_from_user()
# IV,
iv := get_iv_from_storage()
tag := get_tag_from_storage()
encrypted_payload = get_payload_from_storage()
decrypt('aes-256-gcm', password, iv, tag, encrypted_payload)
I'm using PHP in this case, and the openssl_decrypt function returns false
if the decryption didn't work.
Is that a sound authentication method? Can I assume that being able to decrypt the payload successfully validates that the user knows the right password?
Well it sounds obvious now that I'm writing it, but anyway, it's written so I might as well publish the question.
Can I use aes-gcm to authenticate my user? Am I missing anything important? Is there any obvious security issues to this approach?