12
votes

Dois-je couper la chaîne déchiffrée après mcrypt_decrypt?

J'ai un code qui va quelque chose comme: xxx

Je crains que, dans le processus de décodage, le mcrypt_decrypt introduira un espacement ou des caractères nulles gratuits. dos ou devant du $ déchiffréd_string .

si dois-je le couper?

Note: J'aurais pu exécuter le code et le trouver . Mais puisque je ne peux jamais courir assez d'échantillons pour prouver (ou réfuter) mon point, je veux des réponses concrètes et théoriques, probablement basées sur le fonctionnement interne du mcrypt_decrypt algorithme. Une autre raison que je demande est que je crois que cela va aider les autres.

Note 2: Nonobstant avec La réponse ci-dessous (désormais supprimée et seulement 10k utilisateurs peuvent le voir) , il semble que le Exemples ici Utilisez la coupe pour obtenir la chaîne décalprée correcte. < / p>


2 commentaires

Désolé pour la désinformation, Ngu, quand j'ai utilisé McRypt, il semble que j'ai utilisé le mode CBC.


Euh ... je n'avais pas utilisé mode CBC ... :-(


4 Réponses :


18
votes

effectivement mcrypt_encrypt () code> A> et mcrypt_decrypt () code> ainsi que les autres fonctions en / / déchiffrement (comme mcrypt_generic ( ) code> ou mdecrypt_generic () ) DO FORT> PAD STRY> DATA CODE> $ DATA CODE> PARAMÈTRER À une longueur de N * > code>. Le caractère de rembourrage est le caractère nul code> ( \ x0 code> ou \ 0 code>) alors que le > code> dépend sur le chiffrement et les modes de chiffrement de bloc utilisés. Vous devriez consulter Bloquer les modes de fonctionnement Cipher et rembourrage (cryptographie) .

Ce qui suit est la sortie de mcrypt_get_block_size () code> pour chacun des chiffres et modes disponibles sur ma machine. Évidemment, la fonction ne prend pas en compte que des modes tels que BFC, OFB et CTR ne nécessitent aucune mesure spéciale pour gérer les messages dont les longueurs ne sont pas multiples de la taille du bloc, car ils fonctionnent tous en xorant le plaintre avec la sortie du chiffre de bloc em> (citation de Wikipedia). CBC qui est utilisé dans votre exemple nécessite toujours que le bloc final soit rembourré avant le cryptage. p> xxx pré>

par conséquent, vous devez Rtrim () Code> La sortie des fonctions de déchiffrement Pour obtenir la chaîne d'origine si votre chiffre fonctionne sur des blocs de longueur fixe: P>

$output = rtrim($decrypted, "\0");


3 commentaires

Ceci est la solution correcte. Il est très important d'utiliser des guillemets doubles et non des citations simples autour de \ 0 !


BTW, il est très improbable qu'utiliser couper (..., "\ 0") ne vous casseriez jamais des données déchiffrées, même lorsque vous utilisez une taille de bloc non fixe, mais c'est possible Lorsque vous cryptez des données binaires.


Vous êtes un stud @stefangehrig. J'ai trouvé un million d'exemples à l'aide de Cadmin , mais c'était la taille de l'espacement qui importait en réalité dans mon contexte, ce qui pourrait tout ce qui est juste avec le monde à nouveau. Vous savez, après 2 heures de débogage, puis à la recherche d'une solution et tout cela.



8
votes

Dans ma mise en œuvre de Tripledes, j'ai trouvé que la chaîne déchiffrée était rembourrée avec \ 5 ou \ 6 caractères. Ce n'était pas les caractères attendus \ 0 ou \ 4 mentionnés ci-dessus ou dans les exemples PHP.NET. Pour déterminer la valeur ASCII du caractère de rembourrage, utilisez le ORD () fonction . ORD () fonctionne sur un seul caractère afin d'utiliser str_split () pour rompre une chaîne ou accéder au caractère directement avec la notation de tableau - $ string [5].

Résultat de finition - CORRECT ($ DÉCRYPT, " 0 .. \ 32 ");

résultat du code final - xxx


1 commentaires

Il semble que dans certains cas, le rembourrage est déterminé selon RFC 5652 , où le caractère utilisé pour le pad indique en fait la quantité de rembourrage. Je souhaite seulement que je connais que les combinaisons d'algo / mode (ou des versions de bibliothèque sous-jacentes?) Feront ce vs simplement en utilisant "\ 0"!



4
votes

Je devais crypter / déchiffrer des données binaires. Malheureusement, la garniture peut casser les données binaires et couper les bits légitimes qui équivalent à un caractère null.

Pour assurer la taille des données binaires est la même avant et après le cryptage, Rocket Hazmat a publié une excellente réponse ici: Comment puis-je déchiffrer des données binaires Cela s'est terminé par des caractères nul dans PHP? p>

Résumé: P>

// PKCS7 Padding
$blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$pad = $blocksize - (strlen($data) % $blocksize);
$data .= str_repeat(chr($pad), $pad);

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB);


/*  Then somewhere else in your code */
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted, MCRYPT_MODE_ECB);

// PKCS7 Padding
$strPad = ord($decrypted[strlen($decrypted)-1]);
$newData = substr($decrypted, 0, -$strPad);


1 commentaires

Ceci s'applique à CBC de la même manière.



0
votes

Après 24 heures de recherche, finalement cela a fonctionné pour moi: xxx


1 commentaires

Le code de réponse ne fonctionnera pas avec NULL RADDING que PHP MCRYPT par défaut et c'est ce que l'OP utilise. Pour PKCS # 7 / PKCS # 5, le rembourrage doit être un chèque que le rembourrage est valide. Pensez à utiliser la mauvaise clé, $ Strpad serait probablement faux, potentiellement une valeur supérieure à la longueur des données. Mais ne retournez pas une mauvaise erreur de rembourrage, qui a tendance à créer un oracle de rembourrage, tout simplement rien faire. La plupart des bibliothèques prennent en charge le rembourrage du PKCS n ° 7 et ajouteront automatiquement un remplissage sur le cryptage et supprimé le remplissage sur le déchiffrement, rien de plus besoin de ne pas être effectué.