10
votes

Générateur de numéro de pseudo-pseudorandom rapide pour la cryptographie en C

J'utilisais le code suivant pour générer une séquence de nombres pseudo-aléatoires utilisées à des fins cryptographiques, mais j'ai ensuite lu quelque part qu'il peut ne pas être très sécurisé. Quelqu'un peut-il me donner la mise en œuvre d'un meilleur générateur - l'objectif principal est que cette méthode soit rapide. Par exemple, j'ai fait des recherches et rencontré Méthode blum blum , qui tuerait totalement la performance par faire des calculs POW (n).

ps. Et s'il vous plaît ne citez pas les articles Wikipedia avec code C / C ++. Je cherche un échantillon de code C ou C ++ de ce que je montre ci-dessous. xxx


21 commentaires

Je vous conseille fortement d'utiliser un PRNA qui prend en charge Hash-DRBG ou HMAC-DRBG, en particulier si vous avez une intention de certification FIPS. Les algorithmes et leurs exigences sont disponibles sur le Site Nist , et ils sont pas trivial (bonne sécurité rarement).


MERSENNE TWISTER est un bon équilibre entre la vitesse et le «aléatoire». De nombreuses implémentations open-source existent pour de nombreuses langues. Vous pouvez télécharger un C ++ implémentation ici


@Awashburn ou utilisez la mise en oeuvre de dans la norme.


@Rapptz Je ne me suis pas encore familiarisé avec les bibliothèques standard C ++. Si une mise en œuvre de Mersenne Twister existe int Il aléatoire Espace de noms, utilisez ça!


@awashburn Cela fait .


@Awashburn comme notes de la page Wikipedia, la Mersenne Twister n'est pas bonne pour Cryptographics utilise.


@WhozCraig: Wow, mec c'est 128 pages. Une recherche rapide renvoie ce code C: benpfaff.org/writings/clc/prng.cleke/a > Pourrait-il être proche de cela?


Jamais jamais, essayez jamais d'inventer votre propre cryptographie. (Malheureusement, il n'y a que deux types de programmeurs dans le monde: ceux qui n'ont pas besoin d'être informés de cela, et ceux qui n'écouteront pas quand on le dit.)


@NEMO: Je n'ai pas inventé. C'est C rand de C.


@ C00000FD Si vous demandez si cela est proche de la conformité avec Hash-DRGB ou HMAC-DRBG, je dirais non, je regarde simplement la taille du codeBase. Ces algorithmes nécessitent des moteurs de Digest et de nombreuses opérations très spécifiques. Comme je l'ai dit, peu importe si vous n'avez pas besoin de crypto conforme à FIPS (que vous devriez, mais c'est une autre affaire). Le point de PRNG basé sur HASH est l'impossibilité d'inverser le hachage. (et oui, c'est un peu énorme, n'est-ce pas?) =)


@ C00000FD Je pense que Nemo parlait de tout ce que vous aviez construit sur tout ce que vous avez fini. Et je crains qu'il ait raison.


@WhozCraig: OK. J'essaie de trouver une implémentation C / C ++ de Hash-DRBG et jusqu'à présent, tout ce que je reçois est un tas de longs articles et aucun code. Ne me trompez pas, j'aime lire des formules mathématiques, mais c'est facile pour moi de comprendre C / C ++ Code ...


Vous ne pouvez pas utiliser un générateur de nombres aléatoires ordinaire pour les applications cryptographiques. Même ceux qui possèdent d'excellentes propriétés statistiques sont inutiles contre toute attaquante plus sophistiquée qu'un enfant brillant. Un cryptographique RNG est une bête spéciale. Bien que @delnan ait raison, je suis également inquiet de tout ce que vous envisagez de faire avec ces chiffres pseudo-aléatoires. La règle n ° 1 de la cryptographie est d'utiliser la conception de quelqu'un d'autre. La règle de cryptographie n ° 2 est d'utiliser la mise en œuvre de quelqu'un d'autre.


@NEMO: J'apprécie votre préoccupation. Mais si nous appliquons vos règles, il n'y aura pas de cryptographie là-bas ...


Le nombre de personnes qui pensent qu'ils sont des exceptions à ces règles est d'environ 100 fois le nombre de personnes qui sont réellement. À moins que vous n'ayez pas fait sa carrière, vous n'êtes presque certainement pas qualifié pour concevoir ni mettre en œuvre du code cryptographique. Jetez un coup d'œil au 10 Les plus récentes vulnéreuses à OpenSSL. Si vous pouvez vous convaincre que vous n'auriez pas fait de ces erreurs, super. Sinon, faites-vous et vos utilisateurs une faveur et utilisent le code de quelqu'un d'autre .


@NEMO: OK, je ne suis pas à discuter avec vous. Vous dites essentiellement qu'il n'y a pas de cryptographie parfaite et que chaque cryptage peut être brisé avec une quantité suffisante de temps et d'effort. Et je suis d'accord avec ça. Je cherche une solution plus simple et la plus rapide ici ...


@ C00000FD: Pourquoi es-tu si adorable à obtenir le code? Le point de programmation est de le faire vous-même. De plus, rapidement et cryptographiquement sécurisés sont presque toujours en attente. Trouvez quelque chose que travaille (est cryptographiquement sécurisé), puis vous inquiétez de vitesse (une bonne chose qui est inutile du code ne fonctionne pas).


En tant que cryptographe, veuillez trouver une certification sur la bibliothèque de l'étagère ...


@ c00000fd personne n'a jamais accusé le NIST d'être bref.


@brianbeuning lol. Après tout le temps que j'ai passé à couler sur leurs normes, les brouillons et l'addenda, "Bref" m'a sérieusement fait tourner la soda de mon nez. Merci pour le rire.


Pour référence pour les utilisateurs qui sont venus ici et ne savent pas beaucoup de cryptographie ici, c'est un excellent parcours: Coursera.org/course/Crypto


4 Réponses :


-5
votes

Je recommanderais le Mersenne-Twister, que j'ai utilisé le temps et encore.

Le code C est ici . p>

Si vous utilisez C ++ 11, vous avez Mersenne Twister comme une partie de la bibliothèque elle-même. Mersenne Twister est actuellement l'un des meilleurs algorithmes là-bas. P>

Voici comment je voudrais implémenter en C ++ 11, en tant que fonction. C'est très simple. Le MT19937 est Th intégré à Mersenne Twister en C ++ 11. P>

 std::vector<double> classname::mersennetwister(const int& My,const int& Mz,const int& Ny,const int& Nz)
{
int ysize = (My + 2*Ny + 1);
int zsize = (Mz + 2*Nz + 1);
int matsize = ysize*zsize;
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::mt19937_64 generator (seed);
std::uniform_real_distribution<double> distribution(0,1);
std::vector<double> randarray = f.array1dgen(matsize,0);
for (int i=0;i<matsize;++i)
{
   randarray[i] = distribution(generator);
}
return(randarray);
}


7 commentaires

Wikipedia sur les inconvénients de MT: "L'algorithme de sa forme native ne convient pas à la cryptographie (contrairement à un shub blum blum). Observant un nombre suffisant d'itérations (624 dans le cas de MT19937, car c'est la taille du vecteur d'état à partir de laquelle Les itérations futures sont produites) permet de prédire toutes les itérations futures. "


@delnan peut-être qu'il n'a besoin que d'une poignée de nombres aléatoires, beaucoup moins de 624 itérations?


@awashburn alors il irait bien, évidemment. Mais vous ne pouvez pas simplement supposer et recommander une solution qui est cassée si cette hypothèse (souvent déraisonnable) n'est pas vraie.


@Awashburn: Oui, je suis d'accord 624 Les itérations sont trop peu nombreuses ... donc mon seul espoir est quelque chose comme Blum Blum Shub, hah?


@ c00000fd si par "quelque chose comme" Vous voulez dire "quelque chose qui est un CSprng ", puis oui , c'est par définition ce dont vous avez besoin.


MT n'est pas cryptographiquement sécurisé.


Vous ne devriez pas semer le prng avec le temps seulement. Crypto PRNG doit être ensemencé de valeur aléatoire avec une bonne entropie par exemple de la vraie source aléatoire.



17
votes

Isaac ( http://www.burtturtburtle.net/bob/rand/isaacafa. HTML ) est probablement l'un des PRNG cryptographiquement les plus fixes (code sur site). Une autre approche consiste à utiliser un chiffre à bloc en mode compteur. Quelque chose comme Twofish, qui est raisonnablement rapide et disponible librement, serait efficace.

Si vous n'avez pas besoin de nombreux chiffres, tous les systèmes d'exploitation modernes ont des rngs intégrés adaptés à une utilisation cryptographique, bien qu'ils ne puissent généralement pas produire de nombreux nombres car ils s'appuient sur l'entropie accumulant à partir de sources telles que les timings d'entrée. Systèmes de type UNIX (Linux, OSX) a / dev / dev / aléatoires, Windows a CryptGenrandom. Même si ceux-ci ne conviennent pas à vos besoins, vous devez probablement les utiliser pour semer le PRNG que vous finissez par utiliser.


1 commentaires

Maintenant, il y a aussi CHA-CHA à considérer.



5
votes

regarder (ou utiliser) le générateur de nombres aléatoires dans la bibliothèque OpenSSL.

La partie difficile avec tout générateur de nombres aléatoires sécurisé est l'ensemencement. Si vous êtes sous Windows, envisagez d'utiliser Rand_s (). Sur Linux Regardez / dev / urand.

Certaines méthodes d'ensemencement souffrent de ne pas être très aléatoires peu après un redémarrage. Vous pouvez créer un fichier avec des octets aléatoires. Utilisez le fichier et la méthode OS pour l'ensemencement. Utilisez périodiquement votre générateur de nombres aléatoires pour écrire un nouveau fichier.


0 commentaires

1
votes

Ne pas "roulez votre propre" cryptographie. Utilisez une bibliothèque certifiée à la place.

Pour la vitesse, essayez d'utiliser une bibliothèque pouvant fonctionner sur le GPU, qui a beaucoup plus de puissance informatique.


0 commentaires