function __otp_hash($hexstr) { for ($i = 0; $i < 5; ++$i) { $cur[$i] = substr($hexstr, $i * 8, 8); $cur[$i] = pack("L", hexstr2int($cur[$i])); } /* now apply xor algorithm to fold into 64 bit key according to algorithm RFC 2289 : "The secure hash algorithms listed above have the property that they accept an input that is arbitrarily long and produce a fixed size output. The OTP system folds this output to 64 bits using the algorithms in the Appendix A. 64 bits is also the length of the one- time passwords. This is believed to be long enough to be secure and short enough to be entered manually (see below, Form of Output) when necessary." AND "Fold the 160 bit result to 64 bits sha.digest[0] ^= sha.digest[2]; sha.digest[1] ^= sha.digest[3]; sha.digest[0] ^= sha.digest[4];" */ $fin[0] = pack("L", 0x0); $fin[1] = pack("L", 0x0); $cur[0] = $cur[0] ^ $cur[2]; $fin[1] = $cur[1] ^ $cur[3]; $fin[0] = $cur[0] ^ $cur[4]; /* note should force specific byte-order to be little endian here */ return ulong2hexstr($fin[0], 8) . ulong2hexstr($fin[1], 8); // added left-zero padding to force return size of 16 hex digits }
<?php /* LICENSED UNDER THE GPL */ include 'otp_utils.php'; /**********************************************************/ echo "*******************************<BR>"; echo "ulong2hexstr(\$ulong) :<BR>"; echo "*******************************<BR>"; /**********************************************************/ $in = "WWWW"; echo "ulong2hexstr(", $in, ") = ", ulong2hexstr($in), "<BR>"; $in = "WWW"; echo "ulong2hexstr(", $in, ") = ", ulong2hexstr($in), "<BR>"; $in = "WWWWW"; echo "ulong2hexstr(", $in, ") = ", ulong2hexstr($in), "<BR>"; $in = ""; echo "ulong2hexstr(", $in, ") = ", ulong2hexstr($in), "<BR>"; echo "<BR>"; /**********************************************************/ echo "*******************************<BR>"; echo "strhex(\$string) :<BR>"; echo "*******************************<BR>"; /**********************************************************/ $in = "f"; echo "strhex(", $in, ") = ", strhex($in), "<BR>"; $in = "0"; echo "strhex(", $in, ") = ", strhex($in), "<BR>"; $in = "f"; echo "strhex(", $in, ") = ", strhex($in), "<BR>"; $in = "v"; echo "strhex(", $in, ") = ", strhex($in), "<BR>"; $in = "ff";