Je souhaite générer un nombre aléatoire sécurisé à utiliser pour les jetons de porteur dans Vapor Swift.

J'ai regardé OpenCrypto mais il ne semble pas être capable de générer des nombres aléatoires.

Comment puis-je faire cela?

2
swift-lynx 27 août 2020 à 16:06

3 réponses

Meilleure réponse

Pour Vapor, vous pouvez générer un jeton comme ceci:

[UInt8].random(count: 32).base64

Ce sera cryptographiquement sécurisé à utiliser. Vous pouvez l'utiliser comme dans ce dépôt

3
0xTim 28 août 2020 à 16:31

En général (mais continuez à lire), vous aurez besoin de SystemRandomNumberGenerator pour cela. Comme documenté:

SystemRandomNumberGenerator est automatiquement amorcé, peut être utilisé en toute sécurité dans plusieurs threads et utilise un algorithme cryptographiquement sécurisé dans la mesure du possible.

Le "chaque fois que possible" peut vous donner une pause en fonction de la façon dont cela va être déployé. Si c'est sur une liste énumérée de plates-formes, vous pouvez vérifier qu'elles utilisent un CSPRNG. "Presque" (voir ci-dessous) toutes les plates-formes actuelles font:

  • Les plates-formes Apple utilisent arc4random_buf (3).

  • Les plates-formes Linux utilisent getrandom (2) lorsqu'il est disponible; sinon, ils lisent depuis / dev / urandom.

  • Windows utilise BCryptGenRandom.

Sous Linux, getrandom est explicitement approprié à des fins cryptographiques, et bloque s'il ne peut pas encore fournir une bonne entropie. Consultez la source pour sa mise en œuvre . Plus précisément, si le pool d'entropie n'est pas encore initialisé, il bloquera:

if (!(flags & GRND_INSECURE) && !crng_ready()) {
    if (flags & GRND_NONBLOCK)
        return -EAGAIN;
    ret = wait_for_random_bytes();
    if (unlikely(ret))
        return ret;
}

Sur les systèmes sans getrandom, je crois que swift_stdlib_random, que SystemRandomNumberGenerator utilise, peut lire / dev / urandom avant qu'il ne soit initialisé. Il s'agit d'une situation rare (généralement immédiatement après le démarrage, bien que probablement due à d'autres processus consommant rapidement de l'entropie), mais elle peut réduire le caractère aléatoire de vos valeurs. Parmi les plates-formes Swift actuellement prises en charge, je pense que cela n'a d'incidence que sur CentOS 7.

Sous Windows, BCryptGenRandom est documenté pour convenir aux nombres aléatoires cryptographiques:

Le fournisseur de nombres aléatoires par défaut implémente un algorithme pour générer des nombres aléatoires qui respecte la norme NIST SP800-90, en particulier la partie CTR_DRBG de cette norme.

SP800-90 couvre à la fois les exigences d'algorithme et d'entropie.

2
Rob Napier 27 août 2020 à 14:25

Vous voudrez peut-être jeter un œil à SecRandomCopyBytes(_:_:_:):

Depuis la documentation Apple:

Génère un tableau d'octets aléatoires sécurisés par cryptographie.

var bytes = [Int8](repeating: 0, count: 10)
let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)

if status == errSecSuccess { // Always test the status.
    print(bytes)
    // Prints something different every time you run.
}
2
pawello2222 27 août 2020 à 13:16