Thread Frage zu crypt
(12 answers)
Opened by kean at 2009-03-06 10:48
So, nur zum Spaß hab ich jetzt mal eine Funktion geschrieben, die das tut, was crypt() aus der glibc tut:
Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 #!/usr/bin/perl use strict; use warnings; use Digest::MD5 qw(md5); sub mycrypt { my ($plain, $salt) = @_; $salt =~ m#^\$1\$([^\$]*)# or return crypt($plain, $salt); $salt = $1; # chr() und ord() etc. sollen utf8 ignorieren use bytes; # Zunaechst eine MD5-Summe aus $plain und $salt und noch einmal $plain # bauen: my $res = md5($plain . $salt . $plain); # Fuer jedes Zeichen aus $plain kommt ein Zeichen aus der berechneten # MD5-Summe: my $resmult = $res x (length($plain) / 16 + 1); chop $resmult while length($resmult) > length($plain); # Nun bauen wir eine neue MD5-Summe mit komischen Berechnungen aus den # bisherigen Ergebnissen. my $str1 = $plain . '$1$' . $salt . $resmult; for (my $i=length($plain); $i > 0; $i >>= 1) { # Der Kommentar in der glibc sagt, dass dies vermutlich nicht genau so # simpel beabsichtigt war, aber in der urspruenglichen Implementation # effektiv so herauskam. $str1 .= $i % 2 ? chr(0) : chr ord $plain; } $res = md5($str1); # Damit das alles auch recht lange dauert (und nicht so schnell zu knacken # ist), bauen wir in einer Schleife andauernd neue MD5-Summen aus der # jeweils vorherigen Summe sowie $plain und $salt for my $j (0..999) { my $str2 = ''; $str2 .= $j % 2 ? $plain : $res; $str2 .= $salt if $j % 3; $str2 .= $plain if $j % 7; $str2 .= $j % 2 ? $res : $plain; $res = md5($str2); } # Nun ist das Ergebnis schon berechnet, es muessen die Bytes nur noch in # seltsamer Reihenfolge mit Base64 kodiert werden. my $binbuf = ''; my @order = (0, 6, 12, 1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 5, undef, 11); for my $idx (@order) { $binbuf .= defined ($idx) ? sprintf('%08b', ord substr($res, $idx, 1)) : '0000'; } my $txtbuf = ''; my @b64t = ('.', '/', 0..9, 'A'..'Z', 'a'..'z'); while ($binbuf =~ m/(.{24}|.{12})/g) { $txtbuf .= $b64t[oct "0b$_"] for reverse $1 =~ /.{6}/g; } return join '$', '', 1, $salt, $txtbuf; } # Geht ueberall print my $x = mycrypt('hallo welt', '$1$salt'), "\n"; # Geht nur unter Linux print crypt('hallo welt', '$1$salt'), "\n"; # Und das Passwort ueberpruefen: if (mycrypt('hallo welt', $x) eq $x) { print "Passwort richtig!\n"; } Die Lizenz dieses Codes müsste dann wohl LGPL sein. Diese Subroutine sollte man dann am besten noch mit einem Code kombinieren, der zufällige Salts erzeugt. Last edited: 2009-03-11 23:13:19 +0100 (CET) |