1
Hello,

Je suis en train de porter du code de VB.NET vers PHP et je tombe sur un petit os. Dans mon code VB.NET j'ai une fonction qui chiffre une variable texte avec AES-256. Ce chiffrement est dispo sous PHP mais à un détail près: la fonction AES256 sous VB.NET prend une clef ainsi qu'un 'salt' là où en PHP je ne peux spécifier qu'une clef et non un salt mais un vecteur d'initialisation aléatoire sur lequel je n'ai pas la main. De plus PHP me renvoie un warning sur la clef qui serait trop longue pour cette algo (la clef fait 135 caractères). J'ai un jeu de test pour comparer (chaine chiffrée en base64 encodée en VB.NET et en PHP) et effectivement ça ne correspond pas (dû au fait que je n'arrive pas à passer à PHP mon salt d'origine et sans doute aussi car la clef doit être trop grande).

Un aperçu du code VB.NET (clef et salt modifiés) pour que vous puissiez avoir une vue d'ensemble:
string clef = "AAAA..."; // (coupée ici) chaine de 135 caractères (chaine alphanumérique de 45 caractères répétée 3 fois) string salt = "sss..."; // chaine de 16 caractères alphanumériques (dont 2 espaces à la fin sans doute pour du padding) eb_c_CipherClass ebCCipherClass = new eb_c_CipherClass(); Array array = null; // la ligne que j'aimerai porter en PHP array = ebCCipherClass.EncryptString(EB_CRYPT_CIPHER_ALGORITHM.EB_CRYPT_CIPHER_ALGORITHM_RIJNDAEL_CBC_256, clef, salt, "JE SUIS UNE CHAINE A CHIFFRER"); byte[] numArray = new byte[checked(checked(array.get_Length() - 1) + 1)]; array.CopyTo(numArray, 0); string base64String = Convert.ToBase64String(numArray);
Et voici le prototype de la fonction EncryptString (je n'ai aps le source de cette fonction) public virtual extern Array EncryptString([In][ComAliasName("ebCryptLib.EB_CRYPT_CIPHER_ALGORITHM")] EB_CRYPT_CIPHER_ALGORITHM algorithm, [In] string passPhrase, [In] string salt, [In] string plainText);

La lib utilisée est ebcrypt, une sorte de wrapper qui utilise en dessous les libs open source genre openssl. Le site existe toujours mais est vide, il est cependant dispo sur webarchive même si je n'ai pas trouvé d'avantage de docs que la page d'accueil: http://web.archive.org/web/20050206153815/http://www.ebcrypt.com/

Et voici la fonction que j'essaye d'utiliser en PHP: http://php.net/manual/fr/function.mcrypt-encrypt.php
$data = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key,$data, MCRYPT_MODE_CBC, $salt);
Mais il m'envoie bouler et le résultat final (après encodage en base64) ne correspond pas à celui de mon jeu de test...

C'est le dernier bout de code qu'il me reste à porter sur cette grosse appli et loi de Murphy oblige il se trouve que c'est le plus critique. Si on réussit à porter ce code c'en est fini de ce projet! Donc je suis vraiment preneur de votre aide là-dessus! grin
avatar"If you see strict DRM and copy protection that threatens the preservation of history, fight it: copy the work, keep it safe, and eventually share it so it never disappears. [...] no one living 500 years from now will judge your infringing deeds harshly when they can load up an ancient program and see it for themselves."

Benj Edwards - Why History Needs Software Piracy

- - -
Achat ou échange: topic de mes recherches
2
C'est un peu étrange d'utiliser un salt pour de l'AES 256 (qui est une méthode de chiffrement). Normalement, les salt sont utilisés avec les méthodes de hash (qui ne sont pas faites pour être déchiffrées).
Les méthodes de chiffrement utilisent normalement un vecteur d'initialisation (enfin, c'est facultatif, mais c'est le plus courant).

Sinon, arrives-tu à avoir le même résultat que VB (ou PHP) avec openssl en ligne de commande ? Que se passe-t-il avec du texte de 32 octets ?
avatar<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant
3
flanker (./2) :
C'est un peu étrange d'utiliser un salt pour de l'AES 256 (qui est une méthode de chiffrement). Normalement, les salt sont utilisés avec les méthodes de hash (qui ne sont pas faites pour être déchiffrées). Les méthodes de chiffrement utilisent normalement un vecteur d'initialisation (enfin, c'est facultatif, mais c'est le plus courant).

Ouais j'ai tiqué en tombant dessus, peut être sue derrière le salt n'est pas utilisé (le wrapper le demande mais ne l'envoie pas à la lib de chiffrement en dessous). Je vais redemander un jeu de test pour voir si la chaine chiffrée bouge. Si c'est pas le cas alors le salt n'est pas utilisé.
flanker (./2) :
Sinon, arrives-tu à avoir le même résultat que VB (ou PHP) avec openssl en ligne de commande ? Que se passe-t-il avec du texte de 32 octets ?

J'ai pas encore pu essayer je vais voir ça asap.
avatar"If you see strict DRM and copy protection that threatens the preservation of history, fight it: copy the work, keep it safe, and eventually share it so it never disappears. [...] no one living 500 years from now will judge your infringing deeds harshly when they can load up an ancient program and see it for themselves."

Benj Edwards - Why History Needs Software Piracy

- - -
Achat ou échange: topic de mes recherches
4
le salt est possiblement l'IV pour le chainage CBC, ou alors ebcrypt utilise implicitement un IV a zéro sans le dire. il faut l'indiquer a la fonction php.

D'autre part AES CBC ne sait pas chiffrer de chaines arbitraires, mais uniquement des blocs de 16 octets, donc il y a un padding, qui ici n'est défini nulle part dans encrypt.

la fonction php padde avec des zéros.

Je lis aussi et surtout sur le site php que:
Also, MCRYPT_RIJNDAEL_256 is not AES-256, it's a different variant of the Rijndael block cipher. If you want AES-256 in mcrypt, you have to use MCRYPT_RIJNDAEL_128 with a 32-byte key. OpenSSL makes it more obvious which mode you are using (i.e. 'aes-128-cbc' vs 'aes-256-ctr').
C'est probablement ca le problème.

Vive le PHP qui autorise l'utilisation de clés de 256 bits avec l'algo MCRYPT_RIJNDAEL_128 tritop
5
squalyl (./4) :
D'autre part AES CBC ne sait pas chiffrer de chaines arbitraires, mais uniquement des blocs de 16 octets, donc il y a un padding, qui ici n'est défini nulle part dans encrypt.
(c'était exactement pour ça que je proposais du texte de 32o - je ne savais plus si c'était 16 ou 32)
avatar<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant
6
DES blocs de 64 bits
AES blocs de 128 bits (et clés de 128.192.256 bits)

SHA-256 produit des hash de 32 octets.

Le padding n'est pas anodin pour le déchiffrement. Par défaut le déchiffrement d'une chaine arbitraire paddée inclura le padding, car on ne sait pas enlever un padding composé uniquement de zéro (le dernier octet du message peut être un zéro légitime, même si la taille des données est un multiple de la taille du bloc).
On a de la chance avec des chaines C ASCII car on peut remplacer le bloc de zéro final par un simple zéro de fin de chaine, mais ca ne fonctionne pas avec des données arbitraires.

Dans ce cas il faut un "Mandatory padding" défini comme suit:
-on ajoute SYSTEMATIQUEMENT un octet 0x80
-on padde avec des zéros pour arriver au multiple de bloc
note: Si la taille des données a déja la taille du bloc, ben le padding est la quand même.

De cette manière au déchiffrement, on peut retrouver la taille des données originales:
-on enlève tous les zéros de la fin jusqu'a tomber sur 0x80
-on enlève 0x80
-profit!
Ca marche car le padding est 'mandatory', on sait avec certitude qu'il est la même si les données ont la taille des blocs, et qu'il faut l'enlever.
7
squalyl (./4) :

Je lis aussi et surtout sur le site php que:
Also, MCRYPT_RIJNDAEL_256 is not AES-256, it's a different variant of the Rijndael block cipher. If you want AES-256 in mcrypt, you have to use MCRYPT_RIJNDAEL_128 with a 32-byte key. OpenSSL makes it more obvious which mode you are using (i.e. 'aes-128-cbc' vs 'aes-256-ctr').
C'est probablement ca le problème.

Ha bah oui ça explique surement plein de trucs! Du coup MCRYPT n'a pas l'air de gérer RIJNDAEL256, super. Je vais regarder du côté d'openssl.
avatar"If you see strict DRM and copy protection that threatens the preservation of history, fight it: copy the work, keep it safe, and eventually share it so it never disappears. [...] no one living 500 years from now will judge your infringing deeds harshly when they can load up an ancient program and see it for themselves."

Benj Edwards - Why History Needs Software Piracy

- - -
Achat ou échange: topic de mes recherches
8
si, il le gère, lis mon message.

RIJNDAEL256 n'est PAS AES avec des clés de 256 bits
http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=1
For Rijndael, the block length and the key length can be independently specified to any multiple of 32 bits, with a minimum of 128 bits, and a maximum of 256 bits. The support for block and key lengths 160 and 224 bits was introduced in reference [2]. AES fixes the block length to 128 bits, and supports key lengths of 128, 192 or 256 bits only.

si tu veux utiliser AES avec des clés de 256 bits dans mcrypt, tu lui donnes l'algo RIJNDAEL128 MAIS avec une clé qui fait 256 bits et pas 128.
9
squalyl (./4) :
Vive le PHP qui autorise l'utilisation de clés de 256 bits avec l'algo MCRYPT_RIJNDAEL_128

AS2Crypto et autres consorts flash (sick) ne vérifie jamais la taille de l'IV quand tu initialises ton cipher, du coup par exemple dans le code d'un certain site de musique en ligne français, on utilise Blowfish (sick), mais en plus, l'IV fait deux fois la taille du bloc grin (Et c'est l'IV par défaut de la documentation/exemples couic).
oui mais en vrai ca n'en prend qu'un bout, faut savoir lequel et vala.
squalyl (./8) :
si tu veux utiliser AES avec des clés de 256 bits dans mcrypt, tu lui donnes l'algo RIJNDAEL128 MAIS avec une clé qui fait 256 bits et pas 128.

Ok dont la clef de 135 caractères (1080bits?) c'est du bullshit et il suffirait de lui filer 32 caractères (256bits)? à moins que l'algo initial ne prenne que les 32 premiers caractères!

EDIT:

Bon j'ai essayé avec
openssl enc -aes-128-cbcmais pas mieux (j'ai même essayé avec ma clef réduite à 32 caractères au lieu de 135).
avatar"If you see strict DRM and copy protection that threatens the preservation of history, fight it: copy the work, keep it safe, and eventually share it so it never disappears. [...] no one living 500 years from now will judge your infringing deeds harshly when they can load up an ancient program and see it for themselves."

Benj Edwards - Why History Needs Software Piracy

- - -
Achat ou échange: topic de mes recherches
Ils appliquent peut-être une fonction de hachage à la clé pour en obtenir une de la bonne longueur? En tout cas, j'ai fait un minimum de recherche par curiosité, et malheureusement pour toi, le peu que j'ai trouvé comme informations sur cette lib est d'accord sur un point: on ne sait pas ce qu'elle fait, mais il y a des modifications non documentées aux algorithmes de cryptage, ou du moins des étapes non documentées rajoutées. Plusieurs personnes ont essayé de déchiffrer ce qu'elle a chiffré avec d'autres bibliothèques, aucune n'a réussi.
avatarMes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité
t'as rien compris on dirait grin

PHP est merdique, tout seul dans son coin. Pour faire de l'aes256 il faut utiliser la valeur MCRYPT_RIJNDAEL_128 avec une clé de 32 octets (256 bits)

mais dans les autres programmes normaux il faut bien entendu utiliser aes-256-cbc, sinon tu ne fais que de l'aes128 !
squalyl (./13) :
PHP est merdique, tout seul dans son coin. Pour faire de l'aes256 il faut utiliser la valeur MCRYPT_RIJNDAEL_128 avec une clé de 32 octets (256 bits)
!quote
love
avatar<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant
(ben vas-y, ajoute-la au topic kivabien ^^)
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
À mon avis, le problème le plus grand est le comportement d'ebCrypt, pas celui de PHP.
avatarMes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité
squalyl (./16) :
hu? kekjédi?
C'est surtout « so PHP » de prendre RINJDAEL 128 pour utiliser du 256 bits…
avatar<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant
Xr8a
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
Warpten: c'est quoi ton problem avec Blowfish? C'est un des rares algo a ne pas avoir encore été cassé dans la version complete
avatarProud to be CAKE©®™
The cake is a lie! - Love your weighted companion cube

->986-Studio's Wonder Project!<-
[color=DAA5
Mdr Zerosquare grin
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !