Est-il possible de décrypter (conserver la chaîne réelle) le mot de passe qui est enregistré dans db en utilisant l'algorithme SHA1
.
Exemple: si le mot de passe est "password"
Et qu'il est stocké dans db sous "sha1$4fb4c$2bc693f8a86e2d87f757c382a32e3d50fc945b24"
, Est-il possible de conserver la même "password"(string)
de "sha1$4fb4c$2bc693f8a86e2d87f757c382a32e3d50fc945b24"
SHA1
est une fonction de hachage cryptographique, donc l'intention de la conception était d'éviter ce que vous essayez de faire.
Cependant, briser un SHA1
le hachage est techniquement possible. Vous pouvez le faire en essayant simplement de deviner ce qui a été haché. Cette approche par force brute n'est bien sûr pas efficace, mais c'est à peu près la seule façon.
Donc pour répondre à votre question: oui, c'est possible, mais vous avez besoin d'une puissance de calcul importante. Certains chercheurs estiment que cela coûte entre 70 000 $ et 120 000 $ .
Pour autant que nous puissions le dire aujourd'hui, il n'y a pas d'autre moyen que de deviner l'entrée hachée. En effet, des opérations telles que mod
éliminent les informations de votre entrée. Supposons que vous calculez mod 5
et vous obtenez 0
. Quelle a été l'entrée? Était-ce 0
, 5
ou 500
? Vous voyez, vous ne pouvez pas vraiment "revenir en arrière" dans ce cas.
SHA1 est un hachage à sens unique. Vous ne pouvez donc pas vraiment y revenir.
C'est pourquoi les applications l'utilisent pour stocker le hachage du mot de passe et non le mot de passe lui-même.
Comme chaque fonction de hachage, SHA-1 mappe un grand ensemble d'entrée (les clés) à un plus petit ensemble cible (les valeurs de hachage). Ainsi, des collisions peuvent se produire. Cela signifie que deux valeurs de l'ensemble d'entrée correspondent à la même valeur de hachage.
De toute évidence, la probabilité de collision augmente lorsque l'ensemble cible devient plus petit. Mais vice versa, cela signifie également que la probabilité de collision diminue lorsque l'ensemble cible devient plus grand et que l'ensemble cible de SHA-1 est de 160 bits.
Jeff Preshing , a écrit un très bon blog sur Hash Collision Probabilities qui peut vous aider à décider quel algorithme de hachage utiliser. Merci Jeff.
Dans son blog, il montre un tableau qui nous indique la probabilité de collisions pour un ensemble d'entrée donné.
Comme vous pouvez le voir, la probabilité d'un hachage 32 bits est de 1 sur 2 si vous avez 77163 valeurs d'entrée.
Un simple programme Java nous montrera ce que montre son tableau:
public class Main {
public static void main(String[] args) {
char[] inputValue = new char[10];
Map<Integer, String> hashValues = new HashMap<Integer, String>();
int collisionCount = 0;
for (int i = 0; i < 77163; i++) {
String asString = nextValue(inputValue);
int hashCode = asString.hashCode();
String collisionString = hashValues.put(hashCode, asString);
if (collisionString != null) {
collisionCount++;
System.out.println("Collision: " + asString + " <-> " + collisionString);
}
}
System.out.println("Collision count: " + collisionCount);
}
private static String nextValue(char[] inputValue) {
nextValue(inputValue, 0);
int endIndex = 0;
for (int i = 0; i < inputValue.length; i++) {
if (inputValue[i] == 0) {
endIndex = i;
break;
}
}
return new String(inputValue, 0, endIndex);
}
private static void nextValue(char[] inputValue, int index) {
boolean increaseNextIndex = inputValue[index] == 'z';
if (inputValue[index] == 0 || increaseNextIndex) {
inputValue[index] = 'A';
} else {
inputValue[index] += 1;
}
if (increaseNextIndex) {
nextValue(inputValue, index + 1);
}
}
}
Ma sortie se termine par:
Collision: RvV <-> SWV
Collision: SvV <-> TWV
Collision: TvV <-> UWV
Collision: UvV <-> VWV
Collision: VvV <-> WWV
Collision: WvV <-> XWV
Collision count: 35135
Il a produit 35135 collsions et c'est presque la moitié de 77163. Et si j'ai exécuté le programme avec 30084 valeurs d'entrée, le nombre de collisions est 13606. Ce n'est pas exactement 1 sur 10, mais ce n'est qu'une probabilité et l'exemple de programme n'est pas parfait , car il utilise uniquement les caractères ascii entre A
et z
.
Prenons la dernière collision signalée et vérifions
System.out.println("VvV".hashCode());
System.out.println("WWV".hashCode());
Ma sortie est
86390
86390
Conclusion:
Si vous avez une valeur SHA-1 et que vous souhaitez récupérer la valeur d'entrée, vous pouvez essayer une attaque par force brute. Cela signifie que vous devez générer toutes les valeurs d'entrée possibles, les hacher et les comparer avec le SHA-1 que vous avez. Mais cela consommera beaucoup de temps et de puissance de calcul. Certaines personnes ont créé ce qu'on appelle des tables arc-en-ciel pour certains ensembles d'entrée. Mais ceux-ci n'existent que pour certains petits ensembles d'entrée.
Et rappelez-vous que de nombreuses valeurs d'entrée correspondent à une seule valeur de hachage cible. Donc, même si vous connaissiez tous les mappages (ce qui est impossible, car l'ensemble d'entrée n'est pas limité), vous ne pouvez toujours pas dire de quelle valeur d'entrée il s'agissait.
Puisque SHA-1 mappe plusieurs séquences d'octets en une seule, vous ne pouvez pas "décrypter" un hachage, mais en théorie, vous pouvez trouver des collisions: des chaînes qui ont le même hachage.
Il semble que briser un seul hachage coûterait environ 2,7 millions de dollars de temps d'ordinateur actuellement, donc vos efforts sont probablement mieux dépensés ailleurs.