63 lines
1.5 KiB
Plaintext
63 lines
1.5 KiB
Plaintext
== How to fix it in Argon2-cffi
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,python,diff-id=200,diff-type=noncompliant]
|
|
----
|
|
from argon2 import PasswordHasher, profiles
|
|
|
|
def hash_password(password):
|
|
ph = PasswordHasher.from_parameters(profiles.CHEAPEST) # Noncompliant
|
|
return ph.hash(password)
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,python,diff-id=200,diff-type=compliant]
|
|
----
|
|
from argon2 import PasswordHasher
|
|
|
|
def hash_password(password):
|
|
ph = PasswordHasher()
|
|
return ph.hash(password)
|
|
----
|
|
|
|
=== How does this work?
|
|
|
|
include::../../common/fix/argon-parameters.adoc[]
|
|
|
|
To use values recommended by the Argon2 authors, you can use the following objects:
|
|
|
|
* https://argon2-cffi.readthedocs.io/en/stable/api.html#argon2.profiles.RFC_9106_HIGH_MEMORY[argon2.profiles.RFC_9106_HIGH_MEMORY]
|
|
* https://argon2-cffi.readthedocs.io/en/stable/api.html#argon2.profiles.RFC_9106_LOW_MEMORY[argon2.profiles.RFC_9106_LOW_MEMORY]
|
|
|
|
To use values recommended by the OWASP you can craft objects as follows:
|
|
|
|
[source, python]
|
|
----
|
|
from argon2 import Parameters
|
|
from argon2.low_level import ARGON2_VERSION, Type
|
|
|
|
OWASP_1 = argon2.Parameters(
|
|
type=Type.ID,
|
|
version=ARGON2_VERSION,
|
|
salt_len=16,
|
|
hash_len=32,
|
|
time_cost=1,
|
|
memory_cost=47104, # 46 MiB
|
|
parallelism=1)
|
|
|
|
def hash_password(password):
|
|
ph = PasswordHasher.from_parameters(OWASP_1)
|
|
return ph.hash(password)
|
|
----
|
|
|
|
=== Going the extra mile
|
|
|
|
include::../../common/extra-mile/argon-cli.adoc[]
|
|
|
|
include::../../common/extra-mile/peppering.adoc[]
|
|
|