Les numéros de sécurité entre Signal sont dérivés d'un hachage des clés publiques des utilisateurs de la conversation et de leurs numéros de téléphone. Les numéros de sécurité sont utilisés pour s'assurer que la conversation n'a pas été MITM-ed.
Lors de la dérivation des numéros de sécurité, SHA-512 a répété 5200 fois . Selon le Signal safety blog , il y avait des problèmes de confidentialité concernant les numéros de téléphone intégrés dans des hachages. Cependant, cela ne peut pas être la raison, étant donné que l'ensemble des numéros de téléphone possibles est relativement petit.
Commentaires dans le code source:
Plus le nombre d'itérations est élevé, plus le niveau de sécurité est élevé:
- 1024 ~ 109,7 bits
- 1400> 110 bits
- 5200> 112 bits
Alors: quelle est la raison du ralentissement intentionnel du calcul des numéros de sécurité?
Bonus: comment sont calculés approximativement les niveaux de sécurité (1024 hachages SHA-512 ~ 109,7 bits)?
Le commentaire n'est pas très bien expliqué, mais je crois que j'ai déterminé les mathématiques derrière. Le numéro de sécurité est de 60 chiffres de base 10, mais il est créé en deux moitiés de 30 chiffres: l'un basé sur votre numéro de téléphone et votre clé publique, et l'autre basé sur le numéro de téléphone et la clé publique de la personne à qui vous parlez.
En supposant qu'une valeur d'entropie élevée soit convertie en un nombre à 30 chiffres sans perte inutile d'entropie, elle contiendra un journal2(dix30) ≈ 99,66 bits d'entropie, ce qui équivaut à 99,66 "bits de sécurité" (ce qui signifie qu'un attaquant aurait 50% de chances de correspondre à ce numéro de sécurité après 299,66/ 2 = 298,66 hachages). Itérer plusieurs fois augmente les bits de sécurité (car il augmente le nombre d'opérations de hachage pour chaque tentative de l'attaquant):
journal2(dix30 × 1024) ≈ 109,66
journal2(dix30 × 1400) ≈ 110,11
journal2(dix30 × 5200) ≈ 112,00
C'est pour combien de hachages un attaquant devrait effectuer pour correspondre à un numéro de sécurité spécifique, mais si l'attaquant voulait être en mesure de lire les messages que vous lui envoyez, il aurait besoin de connaître le privé clé qui correspond à la clé publique utilisée dans le hachage. La génération de paires de clés RSA coûte cher en calcul, mais ECC est beaucoup plus rapide. Si la génération de paires de clés est suffisamment rapide, il est logique d'itérer le hachage pour augmenter la limite inférieure d'une attaque sur un numéro de sécurité.
Le numéro de sécurité est une dérivation de l'identifiant stable et de la clé publique d'un utilisateur. Les numéros de sécurité sont calculés pour les deux personnes dans une conversation.
Le vrai code important est ce snipit
byte[] publicKey = getLogicalKeyBytes(unsortedIdentityKeys);
byte[] hash = ByteUtil.combine(ByteUtil.shortToByteArray(FINGERPRINT_VERSION), publicKey, stableIdentifier.getBytes());
for (int i=0;i<iterations;i++) {
digest.update(hash);
hash = digest.digest(publicKey);
}
Ce qui se passe, c'est que nous prenons la version d'empreinte digitale, la clé publique et l'identifiant stable comme entrées de départ et que nous hachons une fois avec SHA-512. La deuxième itération ajoute la clé publique au hachage que nous venons de produire, puis la hache une deuxième fois.
Ce processus d'ajout de la clé publique et de répétition du hachage se poursuit pendant le nombre d'itérations indiqué.
Pourquoi devons-nous faire plus d'itérations que par le passé?
Cela est dû à un problème fondamental de hachage. Quelle est la possibilité de collisions de hachage.
Disons que je suis un attaquant (Eve). Alice veut parler à Bob, donc Signal envoie sa clé publique à Bob, mais Eve intercepte la clé publique et la remplace par la sienne. Normalement, il y a une indication que la clé a changé et que le numéro de sécurité change.
SI Eve avait suffisamment de ressources, elle pourrait construire une clé publique correspondant au numéro de sécurité. Pour lutter contre cette menace, nous faisons en sorte qu'Ève ait besoin de trouver une collision qui se produit après 5200 tours de hachage, en ajoutant cette même clé à chaque tour.
Cela devient irréalisable sur le plan du calcul, car chaque cycle de hachage rend la recherche d'une collision linéaire plus coûteuse en termes de calcul. Le nombre d'itérations actuellement choisies est généralement calculé sur la durée d'une attaque de ce style en fonction des ressources de la menace perçue.
Je ne trouve aucun calcul de Signal expliquant précisément pourquoi ils ont choisi 5200.
Ces commentaires dans le code source sont erronés. Le développeur n'a pas vraiment compris ce qu'il a écrit.
Voici son commentaire:
Plus le nombre d'itérations est élevé, plus le niveau de sécurité est élevé
Cette déclaration est partiellement correcte. À savoir, il nécessite plus de ressources pour le forçage brutal et le rend de ce point de vue plus sûr. Mais la probabilité de collisions de hachage dépend uniquement de la taille de l'espace de hachage, c'est-à-dire de la longueur du hachage (en supposant que les hachages sont répartis également). Cela ne dépend pas du nombre d'itérations. Signifie, du point de vue des collisions de hachage, il est pas plus sûr.
Un exemple simple. Supposons que le hachage se compose d'un seul octet, c'est-à-dire de 8 bits. Dans la réalité, personne ne l'utiliserait car il n'est pas sécurisé. Mais permet de mieux comprendre ce qui se passe. 8 bits signifie qu'il existe 256 hachages différents. Peu importe le nombre d'itérations que vous effectuez, 5200 ou 1000000, vous obtenez à la fin l'un des 256 hachages. Quelle est la probabilité d'obtenir l'une des 256 valeurs? C'est 1/256.
Alors pourquoi smb. parler de 5200 itérations -> 112 bits?
Encore une fois, prenons d'abord un hachage de 8 bits = 256 valeurs différentes. De combien de messages avez-vous besoin pour en obtenir un qui produit un hachage donné? Dans le pire des cas, vous avez besoin de 256 calculs. Supposons maintenant que nous utilisons une fonction de hachage qui utilise 2 itérations de la fonction de hachage d'origine. Pour le forcer brutalement, vous avez encore besoin de 256 itérations, chacune étant x2 plus longue que l'original. Cela signifie que vous avez besoin de temps comme 512 hachages originaux, ce qui correspond à 2 ^ 9. Cela équivaut au forçage brutal des valeurs 2 ^ 9 avec la fonction de hachage d'origine. Si nous utilisons 8 itérations, le temps nécessaire est de 256 x 8 = 2 ^ 11, c'est comme utiliser la fonction de hachage d'origine pour 2 ^ 11 valeurs, c'est-à-dire comme augmenter la longueur de hachage de 8 à 11 bits. Pour 5200 itérations, c'est comme augmenter le hachage dans log2 (5200) ~ = 12 bits.
Dans l'OP, l'entropie est de 99,7 bits. Le forçage brutal d'un hachage avec 5200 itérations prend approximativement le même temps que le forçage brutal d'un hachage avec 1 itération mais qui est ~ 12 bits plus long. log2 (5200) ~ = 12,3; 99,7 + 12,3 = 112.
Encore une fois: Il n'est pas correct de dire que l'augmentation du nombre d'itérations équivaut à l'augmentation de la taille de hachage, ou qu'elle augmente l'entropie. Cela augmente seulement le temps CPU nécessaire. Mais le l'entropie reste la même, la probabilité de collisions de hachage reste la même.