问题
I'm having trouble converting the following code from Perl to PHP. In particular, I'm having trouble with this section, as I have no clue what is happening here:
sub md5sum($) {
my @ib = unpack("C*", shift);
my $encstr = join("", map {sprintf('\%3.3o', $_)} @ib);
my ($out) = split(/ /, `printf '$encstr' | md5sum`);
return $out;
}
The main point I'm looking for help on is what does the "C*", shift
do in the unpack statement, what's going on in the join
part, and what does the | md5sum
do at the end of the split
For this section below, I believe I'm also having trouble. My main question here is for the php pack, do I specify the H32, or just the H?
$hexchal = pack "H32", $challenge;
$newchal = pack "H32", md5sum($hexchal . $uamsecret);
my $passvar = "";
$passvar = md5sum("\0" . $password . $newchal);
Here is what I've tried for the section above, but the $hexchal's don't match up
$hexchal = pack("H32", $challenge);
$newchal = md5($hexchal.$uamsecret);
$passvar = md5("\0".$password.$newchal);
回答1:
Code looks a little confusing to me but here's my interpretation:
<1> sub md5sum($) {
<2> my @ib = unpack("C*", shift);
<3> my $encstr = join("", map {sprintf('\%3.3o', $_)} @ib);
<4> my ($out) = split(/ /, `printf '$encstr' | md5sum`);
<5> return $out;
}
the "C*", shift
on <2> converts the string into an array of numbers which is then joined together to form a new string by doing the sprintf formatting on each number. The resultant string is then used a aparameter when executing the command line printf '$encstring' | md5sum
and the return is captured and returned. Effectively this returns with the md5sum ( as returned by the shell command ).
as an example calling the function with 'username' as a parameter will result in the command line being constructed as printf '\165\163\145\162\156\141\155\145' | md5sum
which gives a result of 14c4b06b824ec593239362517f538b29 -
however if we drop the piped md5sum and just execute printf '\165\163\145\162\156\141\155\145'
in a shell then we get the original string of 'username' returned.
It looks to me as though the only reason for the unpack,join and printf is to provide a little more security so processes do not contain the original string should somebody hack the machine and watch the processes etc.
The split on whitespace appears to be used to ommit the trailing - character returned by the command line call so that you only get the md5sum by splitting the retruned string from the command line into 2 values but only capturing the first into the returned $out scalar variable.
I assume that the author of the code could not use the CPAN MD5 module and so fell back to using the command line md5sum command but wanted to obfuscate and command line calls.
You should be able to replace the entire function with a php md5sum function call with just the string as the parameter ( http://php.net/manual/en/function.md5.php )
回答2:
Your PHP code is obviously missing a call to pack
. Try:
$hexchal = pack("H32", $challenge);
$newchal = pack("H32", md5($hexchal.$uamsecret));
$passvar = md5("\0".$password.$newchal);
Alternatively, you can set the raw_output
parameter of PHP's md5
function to TRUE
:
$hexchal = pack("H32", $challenge);
$newchal = md5($hexchal.$uamsecret, TRUE);
$passvar = md5("\0".$password.$newchal);
You should use "H32"
in PHP just like in Perl. It tells pack
to expect 16 bytes (32 nibbles).
来源:https://stackoverflow.com/questions/32921035/trying-to-convert-perl-to-php