== How to fix it in pyca

=== Code examples

include::../../common/fix/code-rationale.adoc[]

==== Noncompliant code example

[source,python,diff-id=2,diff-type=noncompliant]
----
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes

digest = PBKDF2HMAC(hashes.SHA256(), length=32, salt=b"F3MdWpeHeeSjlUxvKBnzzA", iterations=100000).derive(password)
----

==== Compliant solution

[source,python,diff-id=2,diff-type=compliant]
----
import secrets
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes

salt = secrets.token_bytes(32)
digest = PBKDF2HMAC(hashes.SHA256(), length=32, salt=salt, iterations=100000).derive(password)
----

=== How does this work?

include::../../common/fix/salt.adoc[]

Here, the compliant code example ensures the salt is random and has a sufficient
length by calling the `secrets.token_bytes` function. This one internally uses a
cryptographically secure pseudo random number generator.
