J’utilise une bibliothèque Java Scrypt pour le stockage des mots de passe. Il appelle une valeur N
, r
et p
lorsque je crypte les choses, que sa documentation appelle les parameters “Coût du processeur”, “Coût mémoire” et “Coût de parallélisation”. Le seul problème est que je ne sais pas réellement ce qu’elles signifient spécifiquement ou quelles seraient les bonnes valeurs pour elles; Peut-être qu’ils correspondent en quelque sorte aux commutateurs -t, -m et -M activent l’application originale de Colin Percival ?
Quelqu’un at-il des suggestions à ce sujet? La bibliothèque elle-même liste N = 16384, r = 8 et p = 1, mais je ne sais pas si c’est fort ou faible ou quoi.
Au début:
cpercival mentionné dans ses diapositives de 2009 quelque chose autour
Ces valeurs sont assez bonnes pour une utilisation générale (mot de passe-db pour certaines WebApp) même aujourd’hui (2012-09). Bien sûr, les spécificités dépendent de l’application.
En outre, ces valeurs (principalement) signifient:
N
: facteur de travail général, nombre d’itérations. r
: taille de bloc utilisée pour le hachage sous-jacent; affine le coût relatif de la mémoire. p
: facteur de parallélisation; affine le coût CPU relatif. r
et p
sont censés prendre en compte le problème potentiel que la vitesse du processeur, la taille de la mémoire et la bande passante n’augmentent pas comme prévu. Si les performances du processeur augmentent plus rapidement, vous augmentez p
, mais au contraire, une percée dans la technologie de la mémoire offre une amélioration de l’ordre de grandeur, vous augmentez r
. Et N
est là pour suivre le doublement général des performances par intervalle de temps .
Important: toutes les valeurs changent le résultat. (Mis à jour 🙂 C’est la raison pour laquelle tous les parameters scrypt sont stockés dans la chaîne de résultat.
La mémoire nécessaire au fonctionnement du scrypt est calculée comme suit:
128 octets ×
N_cost
×r_blockSizeFactor
pour les parameters que vous citez ( N=16384
, r=8
, p=1
)
128 × 16384 × 8 = 16 777 216 octets = 16 Mo
Vous devez en tenir compte lors du choix des parameters.
Bcrypt est “plus faible” que Scrypt (bien qu’il soit encore trois fois plus puissant que PBKDF2 ) car il ne nécessite que 4 Ko de mémoire. Vous voulez rendre difficile la parallélisation de la fissuration dans le matériel. Par exemple, si une carte vidéo a 1,5 Go de mémoire intégrée et que vous avez réglé le cryptage pour consumr 1 Go de mémoire:
128 × 16384 × 512 = 1 073 741 824 octets = 1 Go
alors un attaquant ne pourrait pas le paralléliser sur leur carte vidéo. Cependant, votre application / téléphone / serveur devra utiliser 1 Go de RAM chaque fois qu’ils calculeront un mot de passe.
Cela m’aide à penser aux parameters de scrypt sous la forme d’un rectangle. Où:
cost
( N ) augmente à la fois l’ utilisation de la mémoire et les itérations . blockSizeFactor
( r ) augmente l’ utilisation de la mémoire . La parallelization
parameters restants ( p ) signifie que vous devez tout faire 2, 3 ou plus:
Si vous aviez plus de mémoire que le CPU, vous pourriez calculer les trois chemins distincts en parallèle – nécessitant trois fois plus de mémoire:
Mais dans toutes les implémentations du monde réel, il est calculé en série, sortingplant les calculs nécessaires:
En réalité, personne n’a jamais choisi un facteur p
autre que p=1
.
Quels sont les facteurs idéaux?
Version graphique de ci-dessus:
Remarques:
r=8
Et zoomé dans la version de ci-dessus à la zone raisonnable:
Je ne veux pas aller sur les excellentes réponses fournies ci-dessus, mais personne ne parle vraiment de la raison pour laquelle “r” a la valeur qu’il a. La réponse de bas niveau fournie par le papier Scrypt de Colin Percival est qu’elle concerne le «produit de bande passante de latence mémoire». Mais qu’est-ce que cela veut vraiment dire?
Si vous faites Scrypt correctement, vous devriez avoir un grand bloc de mémoire qui se trouve principalement dans la mémoire principale. La mémoire principale prend du temps à tirer. Lorsqu’une itération de la boucle de saut de bloc sélectionne d’abord un élément du grand bloc à mélanger dans le tampon de travail, elle doit attendre de l’ordre de 100 ns pour que le premier bloc de données arrive. Ensuite, il doit en demander un autre et attendre qu’il arrive.
Pour r = 1, vous feriez des itérations 4nr Salsa20 / 8 et 2n des lectures de latence depuis la mémoire principale.
Ce n’est pas bien, car cela signifie qu’un attaquant pourrait avoir un avantage sur vous en créant un système avec une latence réduite dans la mémoire principale.
Mais si vous augmentez r et diminuez proportionnellement N, vous pouvez obtenir les mêmes besoins en mémoire et effectuer le même nombre de calculs qu’auparavant, sauf que vous avez échangé des access aléatoires pour des access séquentiels. L’extension de l’access séquentiel permet à la CPU ou à la bibliothèque de récupérer efficacement les blocs de données requirejs suivants. Bien que la latence initiale soit toujours présente, la latence réduite ou éliminée pour les blocs ultérieurs fait en sorte que la latence initiale soit réduite à un niveau minimal. Ainsi, un attaquant gagnerait peu à améliorer sa technologie de mémoire par rapport à la vôtre.
Cependant, il y a un sharepoint diminution des rendements avec l’augmentation de r, et cela est lié au “produit de bande passante de latence de mémoire” mentionné précédemment. Ce que ce produit indique est combien d’octets de données peuvent être en transit de la mémoire principale vers le processeur à un moment donné. C’est la même idée qu’une autoroute – s’il faut 10 minutes pour se rendre du point A au point B (latence) et que la route livre 10 voitures / minute au point B du point A (largeur de bande), la route entre les points A et B contient 100 voitures. Ainsi, le r optimal se rapporte au nombre de blocs de données de 64 octets que vous pouvez demander à la fois, afin de couvrir la latence de cette requête initiale.
Cela améliore la vitesse de l’algorithme, ce qui vous permet d’augmenter N pour plus de mémoire et de calculs ou d’augmenter p pour plus de calculs, comme vous le souhaitez.
Il y a d’autres problèmes avec l’augmentation “r” de trop, ce que je n’ai pas vu beaucoup discuté:
Pour résumer toutes les recommandations:
Un benchmark de ma propre implémentation de Scrypt sur une Surface Pro 3 avec un i5-4300 (2 cœurs, 4 threads), utilisant une constante 128Nr = 16 MB et p = 230; axe gauche est secondes, axe inférieur est valeur r, les barres d’erreur sont +/- 1 écart-type: