######################################### # Perl sub to validate # # Mobile One Time Passwords # # by Stanislav Didilev (irmo@mail.ru) # # based on similar PHP function # # by Ralf Neumann (ralf@njumaen.de) # # based on motp.sourceforge.net # ######################################### # usage: &checkOTP($pin,$otp,$secret); # returns 1(true) if succesfull # returns 0(false) if auth error sub checkOTP { use Digest::MD5 qw(md5_hex); my $pin = @_[0]; my $otp = @_[1]; my $initsecret = @_[2]; my $md5; my $tmp_md5=""; my $i; my $maxperiod = 3*60; # search window in seconds = +/- 3 minutes my $time=time; # get UTC epoch time in seconds for($i = $time - $maxperiod; $i <= $time + $maxperiod; $i++) { $md5 = substr(md5_hex(substr($i,0,-1).$initsecret.$pin),0,6); next if ($md5 eq $tmp_md5); # we are discarding last digit from time, $tmp_md5 = $md5; # so we will have 10 similar results - this code eliminates similar comparissons $otp = lc($otp); chomp($otp); # we are comparing hex numbers as text so we need to check $md5 = lc($md5); chomp($md5); # that they are in the same case and do not contain and symbols if($otp eq $md5) {return 1}; } return 0; }