# `secrets` — Générer des nombres aléatoires de façon sécurisée pour la gestion des secrets

Nouveau dans la version 3.6.

Code source : Lib/secrets.py

Le module `secrets` permet de générer des nombres aléatoires forts au sens de la cryptographie, adaptés à la gestion des mots de passe, à l'authentification des comptes, à la gestion des jetons de sécurité et des secrets associés.

In particular, `secrets` should be used in preference to the default pseudo-random number generator in the `random` module, which is designed for modelling and simulation, not security or cryptography.

Voir aussi

PEP 506

## Nombres aléatoires

Le module `secrets` fournit un accès à la source d'aléa la plus sûre disponible sur votre système d'exploitation.

class `secrets.``SystemRandom`

  Classe permettant de générer des nombres aléatoires à partir des sources d'aléa les plus sûres fournies par le système d'exploitation. Se référer à `random.SystemRandom` pour plus de détails.

`secrets.``choice`(sequence)

  Renvoie un élément choisi aléatoirement dans une séquence non-vide.

`secrets.``randbelow`(n)

  Renvoie un entier aléatoire dans l'intervalle [0, n).

`secrets.``randbits`(k)

  Renvoie un entier de k bits aléatoires.

## Génération de jetons

Le module `secrets` fournit des fonctions pour la génération sécurisée de jetons adaptés à la réinitialisation de mots de passe, à la production d'URLs difficiles à deviner, etc.

`secrets.``token_bytes`([nbytes=None])

  Renvoie une chaîne d'octets aléatoire contenant nbytes octets. Si nbytes est `None` ou omis, une valeur par défaut raisonnable est utilisée.

      >>> token_bytes(16)
      b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'

`secrets.``token_hex`([nbytes=None])

  Renvoie une chaîne de caractères aléatoire en hexadécimal. La chaîne comporte nbytes octets aléatoires, chaque octet étant écrit sous la forme de deux chiffres hexadécimaux. Si nbytes est `None` ou omis, une valeur par défaut raisonnable est utilisée.

      >>> token_hex(16)
      'f9bf78b9a18ce6d46a0cd2b0b86df9da'

`secrets.``token_urlsafe`([nbytes=None])

  Renvoie une chaîne de caractères aléatoire adaptée au format URL, contenant nbytes octets aléatoires. Le texte est encodé en base64, chaque octet produisant en moyenne 1,3 caractères. Si nbytes est `None` ou omis, une valeur par défaut raisonnable est utilisée.

      >>> token_urlsafe(16)
      'Drmhze6EPcv0fN_81Bj-nA'

### Combien d'octets mon jeton doit-il comporter ?

Afin de se prémunir des attaques par force brute, les jetons doivent être suffisamment aléatoires. Malheureusement, l'augmentation de la puissance de calcul des ordinateurs leur permet de réaliser plus de tentatives dans le même laps de temps. De ce fait, le nombre de bits recommandé pour l'aléa augmente aussi. En 2015, une longueur de 32 octets (256 bits) aléatoires est généralement considérée suffisante pour les usages typiques du module `secrets`.

Si vous souhaitez gérer la longueur des jetons par vous-même, vous pouvez spécifier la quantité d'aléa à introduire dans les jetons en passant un argument `int` aux différentes fonctions `token_*`. Cet argument indique alors le nombre d'octets aléatoires utilisés pour la création du jeton.

Sinon, si aucun argument n'est passé ou si celui-ci est `None`, les fonctions `token_*` utilisent une valeur par défaut raisonnable à la place.

Note

Cette valeur par défaut est susceptible de changer à n'importe quel moment, y compris lors des mises à jour de maintenance.

## Autres fonctions

`secrets.``compare_digest`(a, b)

  Renvoie `True` si les chaînes a et b sont égales et `False` sinon, d'une manière permettant de réduire le risque d'attaque temporelle. Se référer à `hmac.compare_digest()` pour plus de détails.

## Recettes et bonnes pratiques

Cette section expose les recettes et les bonnes pratiques d'utilisation de `secrets` pour gérer un niveau minimal de sécurité.

Générer un mot de passe à huit caractères alphanumériques :

    import string
    import secrets
    alphabet = string.ascii_letters + string.digits
    password = ''.join(secrets.choice(alphabet) for i in range(8))

Note

Les applications ne doivent jamais stocker des mots de passe dans un format permettant leur récupération, que ce soit en texte brut ou chiffré. Il convient que les mots de passe soient salés et transformés de façon irréversible par une fonction de hachage cryptographique.

Générer un mot de passe alphanumérique à dix caractères contenant au moins un caractère en minuscule, au moins un caractère en majuscule et au moins trois chiffres :

    import string
    import secrets
    alphabet = string.ascii_letters + string.digits
    while True:
        password = ''.join(secrets.choice(alphabet) for i in range(10))
        if (any(c.islower() for c in password)
                and any(c.isupper() for c in password)
                and sum(c.isdigit() for c in password) >= 3):
            break

Générer une phrase de passe dans le style xkcd :

    import secrets
    # On standard Linux systems, use a convenient dictionary file.
    # Other platforms may need to provide their own word-list.
    with open('/usr/share/dict/words') as f:
        words = [word.strip() for word in f]
        password = ' '.join(secrets.choice(words) for i in range(4))

Générer une URL temporaire difficile à deviner contenant un jeton de sécurité adapté à réinitialisation d'un mot de passe :

    import secrets
    url = 'https://mydomain.com/reset=' + secrets.token_urlsafe()