Hash eines Strings bilden (Thema: PHP Beispiele)

Wie typische Hash-Funktionen in PHP auf einen String angewendet werden können

1. Einleitung

Hashing-Funktionen werden typischerweise dann verwendet, wenn das Handling eines Originalstrings zu aufwändig oder riskant wäre, man aber dennoch diesen Originalstring (häufig zeitversetzt) mit anderen Strings vergleichen will. Dies ist beispielsweise bei Passwörtern der Fall. Das Passwort eines Benutzers soll bei der Registrierung gespeichert werden, sodass bei jedem Login das eingegebene Passwort mit dem gespeicherten verglichen werden kann. Gleichzeitig will man aber auch nicht das Originalpasswort im Klartext in der Datenbank stehen haben, da das für Angreifer ein gefundenes Fressen wäre. Daher wendet man eine Hashing-Funktion auf das Passwort an, welche dieses auf einen anderen String abbildet. Die Zuordnung ist eindeutig und lässt sich von einem Angreifer nicht oder kaum umkehren. (Eindeutig heißt hier, dass jedem Passwort ein bestimmter Hash zugeordnet ist. Jedem Hash können allerdings mehrere Passwörter zugeordnet werden.) Bei jedem Login kann man wiederum den Hash des beim Login verwendeten Passworts bilden und mit dem abgespeicherten Hash vergleichen, um zu ermitteln, ob das eingegebene Passwort gültig ist.

Um die Sicherheit weiter zu erhöhen, werden typischerweise Salts und zusätzliche Iterationen bei der Hash-Berechnung verwendet. Als Salt wird eine weitestgehend oder komplett zufällige Zeichenkette bezeichnet, die an den zu hashenden String angehängt wird. Zusätzliche Iterationen werden verwendet, um die Berechnungszeit des Hashes zu erhöhen. Dadurch wird es für einen Angreifer schwerer, alle erdenklichen Ausgangspasswörter zu bilden, anschließend zu hashen und zuletzt zu testen, welches mit dem Hash übereinstimmt.

2. MD5

Um einen MD5-Hash zu bilden wird die gleichnamige Funktion md5($str) verwendet. Das nächste Beispiel zeigt deren Anwendung:

PHP-Code
<?php
	$str = 'EinMoeglichesPasswort';
	var_dump(md5($str));
?>

HTML-Code: Ausgabe
string(32) "969b59bbb4f0508d46165fce694cfe71"


Der MD5 kann durch einen Salt und mehr Iterationen ergänzt werden. Dafür schreibt man am besten eine kurze eigene Funktion:

PHP-Code
<?php
	function myMd5($str, $salt, $iterations) {
		for ($x=0; $x<$iterations; $x++) {
			$str = md5($str . $salt);
		}
		return $str;
	}

	$str = 'EinMoeglichesPasswort';
	$salt = 'bQ423hbHM8Sbdb9pjquUQU1IWxcxnybBSjqnyBJ23HjqnI3WbkxUQsxnPw813jkq';

	var_dump(myMd5($str, $salt, 100000));
?>

HTML-Code: Ausgabe
string(32) "ef18abc2dc7c04940a862d4612618de6"


3. SHA1

Genauso wie bei MD5 kann auch der SHA1-Hash über die Funktion sha1($str) generiert werden. Nachfolgend direkt mit Salt und mehreren Iterationen:

PHP-Code
<?php
	function mySha1($str, $salt, $iterations) {
		for ($x=0; $x<$iterations; $x++) {
			$str = sha1($str . $salt);
		}
		return $str;
	}

	$str = 'EinMoeglichesPasswort';
	$salt = 'bQ423hbHM8Sbdb9pjquUQU1IWxcxnybBSjqnyBJ23HjqnI3WbkxUQsxnPw813jkq';

	var_dump(mySha1($str, $salt, 100000));
?>

HTML-Code: Ausgabe
string(40) "f10d2abb2e2c385b83526bb7aa83e1106c2345c8"


4. hash() - SHA256, SHA512 und weitere

PHP stellt über md5() und sha1() hinaus auch die Funktion hash($algo, $str) zur Verfügung, welche den String $str anhand des Algorithmus in $algo hasht. Ein solcher Algorithmus könnte zum Beispiel „sha512” sein:

PHP-Code
<?php
	function mySha512($str, $salt, $iterations) {
		for ($x=0; $x<$iterations; $x++) {
			$str = hash('sha512', $str . $salt);
		}
		return $str;
	}

	$str = 'EinMoeglichesPasswort';
	$salt = 'bQ423hbHM8Sbdb9pjquUQU1IWxcxnybBSjqnyBJ23HjqnI3WbkxUQsxnPw813jkq';

	var_dump(mySha512($str, $salt, 10000));
?>

HTML-Code: Ausgabe
string(128) "e7c28c38e5f3cb8a2f842a903272088780fc6fdd569f503815ce5f21914507b363c6cafcff94d7d0b7b32b1eb213128c3a428977931b66db38189f052b408ce6"


5. Hash-Algorithmen und deren Ergebnisse

Die in hash() verwendbaren Algorithmen können über hash_algos() ermittelt werden. Die nachfolgende Tabelle zeigt die Namen aller Algorithmen in Kombination mit beispielhaften Rückgaben und der Zeichenlänge der Rückgabe (die Zeichenlänge ist in der Regel pro Algorithmus konstant, egal welche Daten man übergibt). Es wurde jeweils der String „MeinPasswort” ein Mal gehasht, ohne Salt. Zur besseren Übersichtlichkeit enthalten die Hashes alle 64 Zeichen einen Zeilenumbruch, sodass die Tabelle nicht zu breit wird. Mehrzeilige Hashes sind also als ein String zu interpretieren.

Algorithmus Hash
(Für Beispielstring "MeinPasswort")
Zeichenlänge Hash
md2 38756614017962935ba714c1807a20e4 32
md4 63becbd63c7a04200601c518139be35f 32
md5 1de0d5e5c412890d4071af8ecd8c8ad7 32
sha1 ff0fd0822b5652abadaa7689f307fc3c01221ba7 40
sha224 129b9885d14a1fa5a3f2760f5c2b4fbf8d21530280173b7fdcd093ea 56
sha256 9891cba92a02b9b7a9ae317feab675511657647f63c734b8d882c8624d51fcb7 64
sha384 988e060d5f0cbc2f94d4d5f46ca779572532e17aa15415230cf6dfc1dae0c3d3
d47d202f74135c336e6e3e3f690f29c4
96
sha512 5b4118ed383843c9685d42b8f58dcc59f333a06b145ea1ed0672a35b89bf9d62
5c8b730721ddc1990c5c02788724a14e47eff07dfff836c60aea6fbfd68849e3
128
ripemd128 91df15c1904dfb67b6bae40e015aa9af 32
ripemd160 70ad26d087ff7c2676e025bc6e8aa8bf82ed752b 40
ripemd256 9c2caee6f7a366a35a3335b1bd40fb9df8a578567800a8ee9cf728f5db9ad13b 64
ripemd320 3dc6dd692b6a6faa653beb6fa06686beb9f8f1babe3ae380bfa695b87d3a6cf5
a1823f1d8c477d86
80
whirlpool 78268d6603d3d817be3930e2f55a487f33d79e0ab35e381af586aa992944a878
f691432cca8d0962cb35fba4d0e346e3329d31d6b8b8cff650ebcdab40097367
128
tiger128,3 be197b85c30478ac2244b39c0bcdcbe6 32
tiger160,3 be197b85c30478ac2244b39c0bcdcbe68d19611f 40
tiger192,3 be197b85c30478ac2244b39c0bcdcbe68d19611f48b6aa38 48
tiger128,4 d016b88854bd8264064d814ac4c1440d 32
tiger160,4 d016b88854bd8264064d814ac4c1440d33484fc6 40
tiger192,4 d016b88854bd8264064d814ac4c1440d33484fc63fd83641 48
snefru 248ad0116ee19fc7b5917033c9331e9a33be175b895c31756f84d979df0cd5b6 64
snefru256 248ad0116ee19fc7b5917033c9331e9a33be175b895c31756f84d979df0cd5b6 64
gost 0d2f68fded4a4528ca299d7cf3903c26f6e89898f1067d91ef1dbef551cdd105 64
adler32 1e9004ed 8
crc32 e103f1bd 8
crc32b f9e8d409 8
salsa10 e4e6e7850db3cfc9b7c265e7d880ee48cf95e42874f7b230de91e69e692353c1
369ed29f9f4619f78522fbbb104c99b5e76e31a79db81ba7a59bbe8e4ff0131f
128
salsa20 764fbf639ca462aa7f2b6483a29cdc522e27a4836c96ff02b53ff0fc303a8b37
901c094d7c37062e81e45eaa11bcc0ce91dea43ce36c86db043bb6365490efe9
128
haval128,3 520424857527e69807ebe1e22c8c7627 32
haval160,3 e12eaf2da966b3b3216ff5d48d44e3a74fdae7c2 40
haval192,3 3ebba8db6b3421a5ba287584e29b844fab48ec7ce11270f3 48
haval224,3 afdfaa2982a5c5181ab20a816d9fec183291f32819068ae23fac44e6 56
haval256,3 16de0204a44127606cea646257094c4ca85ae981ef7be7f74e5f0a99e91d767a 64
haval128,4 7c9dc17648dc1bd09bdb5423f33c902d 32
haval160,4 44d37d4a2521a51df115824361eac5e886a254cd 40
haval192,4 8d618e6156be85aa84aab819b13b05895dc68bed9cf536a3 48
haval224,4 b6ff18679eba29e6411961209f6ff40efc4c062992d527da4220c3ee 56
haval256,4 fc0f2425e3d9355bd9eb96a57f24ff8e0643a0587ae9c5a0c5870b48b4f07ecd 64
haval128,5 a239ccfcd74bc57936cf4f52f407c715 32
haval160,5 a2cc1e6df82abe6591625ee398434fd4b2022253 40
haval192,5 dd78cb1606d0d765d7ecc1168053be226bb7723c0b2dddd3 48
haval224,5 56de84767e05f14d98944c6055e9f7959966fac10bac62e69e5de810 56
haval256,5 0b8413f4546e8ace843df1fc6b7481bb19109464b4b97dfc1b39790eac9d933f 64

Die Tabelle wurde mit folgendem Skript erzeugt:

PHP-Code
<?php
	$password = 'MeinPasswort';
?>
<table id="php-hash-algos">
	<thead>
		<tr>
			<th>Algorithmus</th>
			<th>
				Hash<br />
				(Für Beispielstring &quot;<?php echo $password; ?>&quot;)
			</th>
			<th>Zeichenl&auml;nge Hash</th>
		</tr>
	</thead>
	<tbody>
		<?php foreach (hash_algos() as $algo): ?>
			<?php $hash = hash($algo, $password); ?>
			<tr>
				<td><?php echo $algo; ?></td>
				<td><?php echo implode("<br />\n", str_split($hash, 64)); ?></td>
				<td><?php echo strlen($hash); ?></td>
			</tr>
		<?php endforeach; ?>
	</tbody>
</table>

Kommentare (4)

Von neu nach alt
fourth
UnixAdmin (Gast) #
third
ArnoNuehm (Gast) #
second
ArnoNuehm (Gast) #
first
ArnoNuehm (Gast) #