2010-10-27 8 views
4

PHP est l'un de ces langages que j'utilise périodiquement, mais je dois généralement épousseter les toiles d'araignée lorsque je recommence à les utiliser. La même chose s'applique cette semaine pendant que je porte du code C vers PHP. Cela utilise beaucoup de cryptage AES et SHA256 hachage - tout fonctionne bien jusqu'à présent. Cependant, les chaînes décryptées sortent sous la forme "C" - c'est-à-dire terminées avec un octet nul suivi par des octets de remplissage "garbage".Conversion d'une chaîne C ( 0 terminée) en une chaîne PHP

I actuellement « Trim » ces chaînes de style C à la forme PHP avec les éléments suivants:

$iv = strpos($hashsalt8, "\0"); 
if ($iv) 
    $hashsalt8 = substr($hashsalt8, 0, $iv); 

Semble de longue haleine et qu'il devrait y avoir une place appel de fonction d'une ligne, mais je ne peux pas trouver il?

Remarque: Bien que dans ce cas, le nom "hash salt" implique que je pourrais connaître la longueur de la chaîne d'origine, cela est inconnu dans le cas général. Clairement, une solution à une ligne est disponible en utilisant substr() lorsque la longueur est connue a priori.

Répondre

9

Utilisation strstr:

$hashsalt8 = strstr($hashsalt8, "\0", TRUE); 

Une solution plus laid pour les versions inférieures à 5.3.0 (où le troisième paramètre ne sont pas disponibles) utilise les strrev, substr et strrchr fonctions à la place:

$hashsalt8 = strrev(substr(strrchr(strrev($hashsalt8), "\0"), 1)); 
+3

Notez que le troisième paramètre est uniquement disponible en PHP 5.3+. – BoltClock

+0

Ah ça l'explique: je reçois une erreur "nombre de paramètres incorrect", mais en cours d'exécution avec PHP 5.1.6. Si c'était mon propre serveur, je remplacerais probablement le PHP fourni, mais ce n'est pas le cas, donc je ne vais pas essayer. – winwaed

+0

Cela semble être la réponse pour les personnes utilisant des versions ultérieures de PHP. Si rien d'autre qui s'applique à PHP 5.1.6 ne se présente, je vais marquer cela comme la réponse demain. – winwaed

2

Il ne devrait jamais avoir besoin de plus de 32 octets de remplissage à droite? (De votre commentaire ici)

Vous pourriez être en mesure de faire quelque chose comme ceci:

preg_replace('/\x00.{0,32}$/', "", $hashsalt8); 

Notez les guillemets simples au lieu des doubles, si vous utilisez les guillemets le \x00 semble casser :) preg

+0

semble être 32 octets: actuellement 15 octets de courrier indésirable dans la première instance. Approche intéressante, mais la simplicité est peut-être une chose subjective (j'ai tendance à ne pas aimer les regex pour les problèmes simples). – winwaed

+0

Vous pouvez * utiliser * des guillemets doubles, juste échapper la barre oblique inverse pour obtenir '\\ x00' et il ne sera pas interprété par PHP comme un octet nul, mais littéralement' \ x00'. – BoltClock

2

La fonction strtok fera en un seul passage au lieu de deux:

$hashsalt8 = strtok($hashsalt8, "\0");

Depuis PHP 4.1.0, cependant, strtok ne retournera pas une chaîne vide si la chaîne d'entrée commence par un octet zéro. Vous pouvez faire ce qui suit pour traiter ce cas:

 
if ($hashsalt8[0] == "\0") { 
    $hashsalt8 = ''; 
} 
else { 
    $hashsalt8 = strtok($hashsalt8, "\0"); 
} 

Notez qu'une chaîne d'entrée en commençant par un octet nul expose aussi un bug dans votre code actuel. Dans ce cas, strpos renverra 0 et if ($iv) échouera.

Vous devez utiliser l'opérateur !== de faire la différence entre 0 et false:

 
$iv = strpos($hashsalt8, "\0"); 
if ($iv !== false) { 
    $hashsalt8 = substr($hashsalt8, 0, $iv); 
} 
+0

Merci! Oui ce serait "simple". Merci aussi pour la note sur l'opérateur! ==. Je ne pense pas que cette situation se produise pour mon code spécifique mais c'est clairement la bonne chose à faire pour le cas général (ou même la programmation sécurisée en général) – winwaed