GNT sans publicité, site mobile, fonctionnalitées exclusives...

chiffrement AES et gonflement du fichier d'origine

Le
Kevin Denis
Bonjour,

j'utilise openSSL pour faire quelques tests de chiffrement. Un point
m'étonne, concernant le salage:

$ dd if=/dev/urandom ofQ2octets bsQ2 count=1
$ openssl enc -aes-128-cbc -nosalt -in 512octets -pass pass:word -out nosalt1
$ openssl enc -aes-128-cbc -nosalt -in 512octets -pass pass:word -out nosalt2
$ openssl enc -aes-128-cbc -nosalt -in 512octets -pass pass:word -out nosalt3
$ openssl enc -aes-128-cbc -salt -in 512octets -pass pass:word -out salt1
$ openssl enc -aes-128-cbc -salt -in 512octets -pass pass:word -out salt2
$ openssl enc -aes-128-cbc -salt -in 512octets -pass pass:word -out salt3
$ sha256sum *salt*
0abe59946b9ba78bc2a623621268f9f23ddc6d3a30d6b16a5395fbb0718700f2 nosalt1
0abe59946b9ba78bc2a623621268f9f23ddc6d3a30d6b16a5395fbb0718700f2 nosalt2
0abe59946b9ba78bc2a623621268f9f23ddc6d3a30d6b16a5395fbb0718700f2 nosalt3
b64df3b8f17c9d5dc5045e10c725d3b7fefae052451e4c6620b34a48f89d520d salt1
5be23d8e04ecfcf2f7391a030896d7cb570237b71ff6888707806a6af8aa2883 salt2
74bb1e04e0cc8f6179490aa6d60fc2cef91aee8dd8c125de518450a69762b5e1 salt3

Jusque là, normal. Le chiffrement non salé donne toujours le même
résultat, le chiffrement salé change.

Mais:
$ ls -l *salt*
-rw-r--r-- 1 kevin users 528 2010-11-08 12:36 nosalt1
-rw-r--r-- 1 kevin users 528 2010-11-08 12:36 nosalt2
-rw-r--r-- 1 kevin users 528 2010-11-08 12:36 nosalt3
-rw-r--r-- 1 kevin users 544 2010-11-08 12:36 salt1
-rw-r--r-- 1 kevin users 544 2010-11-08 12:36 salt2
-rw-r--r-- 1 kevin users 544 2010-11-08 12:36 salt3

J'aurai pensé que le chiffrement non salé conservait la taille
d'origine du fichier. Il n'en est pas le cas. (le fichier salé est plus
gros que le fichier non salé, ce qui me semble normal).

Quels sont ces 16 octets en plus?
Merci
--
Kevin
Lire les 8 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Francois Grieu
Le #22772811
Le 08/11/2010 12:39, Kevin Denis a écrit :
Bonjour,

j'utilise openSSL pour faire quelques tests de chiffrement. Un point
m'étonne, concernant le salage:

$ dd if=/dev/urandom ofQ2octets bsQ2 count=1
$ openssl enc -aes-128-cbc -nosalt -in 512octets -pass pass:word -out nosalt1
$ openssl enc -aes-128-cbc -nosalt -in 512octets -pass pass:word -out nosalt2
$ openssl enc -aes-128-cbc -nosalt -in 512octets -pass pass:word -out nosalt3
$ openssl enc -aes-128-cbc -salt -in 512octets -pass pass:word -out salt1
$ openssl enc -aes-128-cbc -salt -in 512octets -pass pass:word -out salt2
$ openssl enc -aes-128-cbc -salt -in 512octets -pass pass:word -out salt3
$ sha256sum *salt*
0abe59946b9ba78bc2a623621268f9f23ddc6d3a30d6b16a5395fbb0718700f2 nosalt1
0abe59946b9ba78bc2a623621268f9f23ddc6d3a30d6b16a5395fbb0718700f2 nosalt2
0abe59946b9ba78bc2a623621268f9f23ddc6d3a30d6b16a5395fbb0718700f2 nosalt3
b64df3b8f17c9d5dc5045e10c725d3b7fefae052451e4c6620b34a48f89d520d salt1
5be23d8e04ecfcf2f7391a030896d7cb570237b71ff6888707806a6af8aa2883 salt2
74bb1e04e0cc8f6179490aa6d60fc2cef91aee8dd8c125de518450a69762b5e1 salt3

Jusque là, normal. Le chiffrement non salé donne toujours le même
résultat, le chiffrement salé change.

Mais:
$ ls -l *salt*
-rw-r--r-- 1 kevin users 528 2010-11-08 12:36 nosalt1
-rw-r--r-- 1 kevin users 528 2010-11-08 12:36 nosalt2
-rw-r--r-- 1 kevin users 528 2010-11-08 12:36 nosalt3
-rw-r--r-- 1 kevin users 544 2010-11-08 12:36 salt1
-rw-r--r-- 1 kevin users 544 2010-11-08 12:36 salt2
-rw-r--r-- 1 kevin users 544 2010-11-08 12:36 salt3

J'aurai pensé que le chiffrement non salé conservait la taille
d'origine du fichier. Il n'en est pas le cas. (le fichier salé est plus
gros que le fichier non salé, ce qui me semble normal).

Quels sont ces 16 octets en plus?
Merci



Je conjecture que openssl enc -aes-128-cbc -nosalt fait en sorte
que chiffrer puis déchiffrer n'importe quel fichier le laisse
inchangé, y compris sa longueur.
Ceci rend inévitable d'allonger un peu la longueur de certains
fichiers: AES opérant par blocs de 16 octets, les fichiers de
1 à 15 octets chiffrés avec aes-128-cbc font inévitablement
16 octets au moins, ce qui ne laisse plus assez de fichiers
chiffrés de 16 octets pour que les fichiers de 16 octets chiffrés
fassent 16 octets.
La technique la plus courante est ISO/IEC 9797-1 Padding Method 2:
on ajoute un octet à 0x80 puis d'autant d'octet à 0x00 qu'il faut
pour atteindre un multiple la taille de bloc. Ce qui dans le
contexte fait que chiffrer n octets produit n+16-(n%15) octets.

Je ne sais pas quelle méthode utilise OpenSSL, il y a l'embarras
du choix
http://en.wikipedia.org/wiki/Paddin...ng_methods
http://fr.wikipedia.org/wiki/Rempli...graphie%29

François Grieu
Thomas Pornin
Le #22772801
According to Kevin Denis
J'aurai pensé que le chiffrement non salé conservait la taille
d'origine du fichier. Il n'en est pas le cas.



AES est un algorithme de chiffrement par blocs. Il transforme des
blocs de 16 octets en d'autres blocs de 16 octets. Le mode CBC suppose
que l'entrée a une taille multiple de 16. Comme le mode "enc" accepte
des entrées de taille arbitraire, OpenSSL est bien obligé d'appliquer
ce qu'on appelle du "padding" : rajouter des octets au bout, de telle
sorte que :
1. la taille après padding soit multiple de 16
2. au déchiffrement, on puisse enlever sans ambiguité le padding

En réfléchissant un peu, on peut voir qu'il est mathématiquement
impossible de réaliser ces deux propriétés sans devoir étendre
_systématiquement_ la taille. Autrement dit, si la taille d'entrée est
déjà multiple de 16, alors il va falloir aller au multiple de 16
suivant. C'est ce que fait le padding PKCS#5 : ça rajoute n octets
(n >= 1) qui ont la valeur numérique "n". Ainsi, au déchiffrement,
on peut regarder le dernier octet obtenu, et ainsi savoir combien
d'octets sont du padding et doivent être enlevés.

Il existe de nombreuses variantes sur ce principe, et, par ailleurs,
comme c'est de la cryptographie et non des mathématiques, on a parfois
des ruses applicables (il y en a une qui s'appelle CTS, comme
"ciphertext stealing", qui permet de faire ça). Il y a aussi d'autres
modes de chiffrement, distinct de CBC (par exemple CTR) qui n'ont pas
besoin d'une entrée de taille multiple de 16.

En bref, pour enlever des 16 octets supplémentaires, ajoutez l'option
"-nopad", mais il faudra alors que l'entrée ait toujours une taille
multiple de 16.


Il convient de noter que :

1. Ce que fait OpenSSL avec la commande "openssl enc" n'est compatible
qu'avec OpenSSL, et encore, pas toutes les versions.

2. Utiliser un mot de passe sans "salt" est un risque de sécurité. Cela
permet d'optimiser une recherche sur le mot de passe (dans le sens
suivant : l'attaquant devra se payer le dictionnaire, mais il
pourra le faire _une_ fois, et attaquer ensuite de nombreux messages
chiffrés avec des mots de passes différents).

3. Le mode CBC nécessite une IV. OpenSSL dérive cette IV du mot de
passe. Cela veut dire qu'en mode "nosalt", si on utilise le même
mot de passe deux fois, on va aussi utiliser la même IV. C'est
_aussi_ un problème de sécurité avec CBC (pas le même que le point 2).


--Thomas Pornin
Thomas Pornin
Le #22772791
According to Francois Grieu
La technique la plus courante est ISO/IEC 9797-1 Padding Method 2:



Ça doit dépendre des domaines. Dans le mien, c'est PKCS#5 qui est
utilisée le plus souvent (et, d'après le manuel d'OpenSSL, c'est ce
qu'OpenSSL applique en l'occurrence). L'effet est le même : au moins
un octet en plus, et on atteint le multiple de 16 suivant.


--Thomas Pornin
Kevin Denis
Le #22773191
Le 08-11-2010, Thomas Pornin
En bref, pour enlever des 16 octets supplémentaires, ajoutez l'option
"-nopad", mais il faudra alors que l'entrée ait toujours une taille
multiple de 16.



Ok, ça fonctionne. Je travaille avec des multiples de 512 qui sont bien
évidemment aussi multiples de 16.

Il convient de noter que :

1. Ce que fait OpenSSL avec la commande "openssl enc" n'est compatible
qu'avec OpenSSL, et encore, pas toutes les versions.



Je pensais qu'openssl était standard, dans le sens ou un (dé)chiffrement
effectué par lui est utilisable par n'importe quel autre programme (?)

2. Utiliser un mot de passe sans "salt" est un risque de sécurité. Cela
permet d'optimiser une recherche sur le mot de passe (dans le sens
suivant : l'attaquant devra se payer le dictionnaire, mais il
pourra le faire _une_ fois, et attaquer ensuite de nombreux messages
chiffrés avec des mots de passes différents).



Comment fonctionnent alors les systèmes de Full Disk Encryption? Ils
ont un espace chiffré égal à l'espace disque (moins quelques octest
négligeables d'en-tête). Et si le chiffré est égal en taille au clair,
alors pas de salt? Ce qui signifierait donc une diminution de la
sécurité. Mais si on ajoute du salt, alors l'espace disque "chiffrable"
est bien plus petit que l'espace disque réel. Comment est résolu ce
problème?

3. Le mode CBC nécessite une IV. OpenSSL dérive cette IV du mot de
passe. Cela veut dire qu'en mode "nosalt", si on utilise le même
mot de passe deux fois, on va aussi utiliser la même IV. C'est
_aussi_ un problème de sécurité avec CBC (pas le même que le point 2).



Je spécifie moi même l'iv en fait, dans mes tests.

Merci
--
Kevin
Thomas Pornin
Le #22773341
According to Kevin Denis
Je pensais qu'openssl était standard, dans le sens ou un (dé)chiffrement
effectué par lui est utilisable par n'importe quel autre programme (?)



L'implémentation d'AES est standard : pour une même clé de 128 bits, un
bloc de 16 octets sera transformé dans le même bloc chiffré que ce que
produit n'importe quelle autre implémentation de l'AES.

Mais de l'AES à un chiffrement de message par mot de passe, il y a un
pas. Ce que fait "openssl enc" est une tambouille spécifique à OpenSSL
et qui n'est décrite nulle part ailleurs que dans le code source
d'OpenSSL.

Il faut dire que les standards de chiffrement de messages sont un peu
plus "haut niveau" que ça. Par exemple, S/MIME est un standard de
chiffrement et signature d'emails. S/MIME utilise CMS, dérivé de PKCS#7.
OpenSSL a une implémentation de S/MIME ("openssl smime").


Comment fonctionnent alors les systèmes de Full Disk Encryption?



Une salt est un élément de sécurité important dans la transformation
d'un mot de passe en une clé. Pour être précis, un "mot de passe" est
une information confidentielle qui peut rentrer dans le cerveau d'un
humain, et est donc vulnérable aux recherches exhaustives, parce que les
cerveaux humains sont comme ça, ils ne sont pas très doués pour la
mémorisation. La salt est un mécanisme qui s'assure que si un mot de
passe donné est attaquable avec un certain coût, l'attaquant devra payer
ce coût pour _chaque_ mot de passe attaqué, sans possibilité de partage
de l'effort.

Un système de chiffrement de disque dur, même s'il est protégé par un
mot de passe, va d'abord se fabriquer une unique clé maître, de grande
taille, qui servira pour tout le disque. Comme on souhaite en général
pouvoir changer le mot de passe, la technique usuelle est de choisir une
grosse clé maître aléatoire, et de stocker cette clé dans un entête,
chiffrée symétriquement avec une clé dérivée du mot de passe (c'est là
et seulement là qu'il y a une salt).

Pour le reste, il faut encore se préoccuper des IV. Si on considère le
disque entier comme un unique gros message en mode CBC, alors, pour
déchiffrer un secteur, il faut lire ce secteur _et_ les derniers 16
octets du secteur précédent. C'est un peu pénalisant du point de vue
performances. Une autre méthode est de considérer chaque secteur (de 512
octets) comme un message indépendant, et d'utiliser comme IV une valeur
dérivée de la clé et du numéro de secteur (c'est un peu délicat à faire :
on veut des IV réparties uniformément dans l'espace des blocs de 16
octets, et imprédictibles). Une autre méthode encore consisterait à
ne pas utiliser le mode CBC, mais le mode CTR, où le numéro de
secteur donne naturellement les informations nécessaires.

Si on veut en outre du contrôle d'intégrité, alors c'est plus compliqué.
Beaucoup plus.


--Thomas Pornin
Publicité
Suivre les réponses
Poster une réponse
Anonyme