PBKDF2 et génération des clés de chiffrement de disque

Dans mon billet sur les flops et le temps pour casser un password par brute force. Je prenais uniquement en compte la puissance en FLOPS sans prendre en compte le type de hash et les itérations. J’ai récemment parlé dans un billet du temps nécessaire à un supercalculateur pour casser un mot de passe issus d’une fonction de hash. En partant du postulat : 1 FLOPS = 1 hash. A présent je vais essayer de calculer le temps nécessaire à ce même supercalculateur pour casser une clé réalisé non pas seulement un hash mais avec une fonction de type PBKDF2.

Le PBKDF2 (Password-Based Key Derivation Function) est une fonction de dérivation de clé qui est implémenté dans la majorité des logiciel de chiffrement de disque. C’est aujourd’hui la meilleure référence en matière de sécurité pour la création de clé de chiffrement. Il est basé sur ces éléments :

  • Un algorithme de HMAC (SHA512, RIPEMD, WHIRLPOOL,etc)
  • Un mot de passe
  • De la Salt pour luter contre une attaque rainbow table
  • Des itérations pour ralentir la génération de clé

Ces itérations sont très importantes car elles permettent d’accroitre considérablement le temps nécessaire au test de toutes les combinaisons d’un mot de passe. Et c’est sur cela que ce billet va se concentrer.

Je vais reprendre l’excellent travail d’explication du fonctionnement de Truecrypt de Bjorn Edstrom et ses fonctions en python. Dans un premier temps je vais chercher à générer une clé PBKDF2-PKCS#5, puis dans un second temps je vais chercher à calculer le temps qu’il faut pour la générer la clés en fonctions des différents éléments la composant.

1 / Les algorithmes de hachage

Truecrypt utilise soit le RIPEMD-160 soit du WHIRLPOOL soit du  SHA512 comme générateur de hash. Le RIPEMD-160 et le WHIRLPOOL sont tous les 2 issus du standard ISO/IEC 10118-3:2004 alors que le SHA512 est issus du FIPS PUB 180-2. Dans les 2 cas se sont des standards récent qui date respectivement de 2004 et 2002.

Le RIPEMD est considéré comme le plus faible des 3 car il génère un résultat que sur 160bits, alors que les 2 autres font un hash de 512bits. Pour palier à ce manque, Truecrypt fait 2000 itérations à cet algorithme au lieu de 1000 comme pour les 2 autres.

Le SHA-512 est de la famille du SHA-2 qui est dérivé du SHA-1. Le SHA-1 possède des failles qui ont été découverte en 2005, sont remplacement par le SHA-3 est en cours.

2 / Hash, HMAC et PBKDF2

Voici rapidement l’explication des différentes fonctions.

Le hash est  l’empreinte d’un mot de passe généré par un algorithme à sens unique (SHA, MD5, RIPEMD, Whirlpool, etc).

Le HMAC est une fonction de hash qui va créer l’empreinte d’un texte tout en le combinant avec un mot de passe.

Une fonction PBKDF2 combine un HMAC, un texte, de la salt et des itérations.

3 / Générer le hash d’un password en python

Tout d’abord je vais chercher à savoir combien de temps prend mon ordinateurs pour générer le hash d’un password.  Pour cela il faut télécharger d’abord les 2 librairies ripemd et whirlpool qui ne sont pas implémenté par défaut en python contrairement au SHA512.

Puis dans un SHELL python on va les tester :

import whirlpool
whirlpool.new("artiflo.net").hexdigest()
'220f227652e6af8b180697d416d387e73917c4d8a69360dd0e5dd5520dbf1684b09883bd2b5dcc4ae75fa93765b8aa7484be225a43ce12ab3ff11d0b700da4eb'

import ripemd
ripemd.new("artiflo.net").hexdigest()
'b6fb9b189dc3089fb4565948f9187bf07bfa6323'

from hashlib import sha512
sha512("artiflo.net").hexdigest()
'fb5b25552b64cde7e901a2097a900835b96dff747b95ce97eaaeb8e3088abdbf9c2eb54f467e6c6c9f45c6b431552579a4cf21bdae92f6e7e915d4a70d639982'

Comme prévu, le hash généré par le RIPEMD ne fait que 160bits il est plus court que les hash de 512bits de SHA512 et Whirlpool.

Maintenant qu’on peut générer un hash, il faut timer l’opération en utilisant la fonction timeit de python (Le résultat est donnée en seconde) :

import whirlpool
import timeit
timeit.Timer(stmt='whirlpool.new("password").hexdigest()', setup='import whirlpool').timeit(1)
0.0012343376151203668

import ripemd
timeit.Timer(stmt='ripemd.new("password").hexdigest()', setup='import ripemd').timeit(1)
0.00041234010131928941

from hashlib import sha512
timeit.Timer(stmt='sha512("password").hexdigest()', setup='from hashlib import sha512').timeit(1)
1.2002927298731502e-05

Tous ces résultat sont donnés en hexdigest() qui contrairement au digest() retourne uniquement des caractères hexadécimaux. Pour indication voici un tableau comparant les performances entre le hexdigest() et le digest().

Type de retour Temps WHIRLPOOL Temps RIPEMD160 Temps SHA512
hash digest 0,000718894 0,000397197 9,13E-06
hash hexdigest 0,001234338 0,00041234 1,20E-05
Différence 71,70% 3,81% 31,41%

La différence est essentiellement du à l’implémentation de la fonction de hachage et son optimisation.

Pages: 1 2

6 comments to PBKDF2 et génération des clés de chiffrement de disque

Leave a Reply

  

  

  

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>