J'ai un code qui va quelque chose comme: Je crains que, dans le processus de décodage, le si dois-je le couper? p> 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 Note 2: Nonobstant avec La réponse ci-dessous (désormais supprimée et seulement 10k utilisateurs peuvent le voir) , il semble que le mcrypt_decrypt code> introduira un espacement ou des caractères nulles gratuits. dos ou devant du $ déchiffréd_string code>. p> mcrypt_decrypt code> algorithme. Une autre raison que je demande est que je crois que cela va aider les autres. Strong> p>
4 Réponses :
effectivement Ce qui suit est la sortie de par conséquent, vous devez 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) . 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> 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");
Ceci est la solution correcte. Il est très important d'utiliser des guillemets doubles et non des citations simples autour de \ 0 code>!
BTW, il est très improbable qu'utiliser couper (..., "\ 0") code> 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 I> Lorsque vous cryptez des données binaires.
Vous êtes un stud @stefangehrig. J'ai trouvé un million d'exemples à l'aide de Cadmin CODE>, 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.
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 - résultat du code final - p> CORRECT ($ DÉCRYPT, " 0 .. \ 32 "); code> p>
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"!
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);
Ceci s'applique à CBC de la même manière.
Après 24 heures de recherche, finalement cela a fonctionné pour moi:
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é.
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 ... :-(