2013-09-30 2 views
0

Я изо всех сил пытался узнать, как HOTP (коды на основе HOTP для Android Google Authenication). Я нашел этот код, который имеет возможность совместно использовать секретный ключ между сервером и клиентом (Mobile APP).PHP одноразовый пароль?

<?php 
function oath_hotp($key,$counter) { 

    // Convert to padded binary string 
    $data = pack ('C*', $counter); 
    $data = str_pad($data,8,chr(0),STR_PAD_LEFT); 

    // HMAC 
    return hash_hmac('sha1',$data,$key); 
} 

function oath_truncate($hash, $length = 6) { 

    // Convert to dec 
    foreach(str_split($hash,2) as $hex) { 
     $hmac_result[]=hexdec($hex); 
    } 

    // Find offset 
    $offset = $hmac_result[19] & 0xf; 

    // Algorithm from RFC 
    return (
     (($hmac_result[$offset+0] & 0x7f) << 24) | 
     (($hmac_result[$offset+1] & 0xff) << 16) | 
     (($hmac_result[$offset+2] & 0xff) << 8) | 
     ($hmac_result[$offset+3] & 0xff) 
     ) % pow(10,$length); 
} 

print "<pre>"; 
print "Compare results with:"; 
print " http://tools.ietf.org/html/draft-mraihi-oath-hmac-otp-04\n"; 
print "Count\tHash\t\t\t\t\t\tPin\n"; 
for($i=0;$i<10;$i++){ 
    print $i."\t".($a=oath_hotp("mysecretvalue",$i)); 
    print "\t".oath_truncate($a)."\n"; 
} 
?> 

Этот выход следующий -

Compare results with: http://tools.ietf.org/html/draft-mraihi-oath-hmac-otp-04 
Count     Hash      Pin 
0 f25e6c58cc7a2dfedae7eb48a1bff891aa0c0189 472801 
1 b52adf13022511f08740566fb44c0b267d7c2604 983856 
2 3c693c66f6e04178943dc9badc0dd41318dbc7f7 981065 
3 1225cf508043a59fe2e39e335ff5f3e5795131ba 683381 
4 21a9756e8de58df5e10c9292e0147823ba03539b 675192 
5 7339c3496cebdaf3a035eaba888f61d8c19d8cf9 575624 
6 c7c03ce2174f144a329664d35cc90e70a3686596 406934 
7 431a75f26b9950f0206911667f3a2ed7fdfc43c7 172241 
8 81e05a2d9e060a25f515b1e53170dce4daad5cc7 818865 
9 ff2068918dc53db45a0c338d8de99419cf3cb571 723917 

Теперь моя проблема в том, что я не могу управлять для выше кода для правильной работы на стороне клиента, так и на стороне сервера. Я использовал тот же секретный ключ print $i."\t".($a=oath_hotp("**mysecretvalue**",$i)); Выход полностью отличается. Обратите внимание, что это счетчик, который означает, что нет синхронизации времени, например TOTP.

Я удвоил свой секретный код на своем телефоне и на стороне сервера Android. Что может быть неправильным? Обратите внимание, что я не очень хорошо знаком с защитой PHP. Поэтому, если вышеуказанное не работает с аутентификацией Google, предоставьте мне место для начала.

Спасибо

ответ

1

Google Authenticator принимает входной секрет, как RFC 3548 base32 (https://code.google.com/p/google-authenticator/) и вы используете секрет, который ASCII.

Код php у вас в порядке (вы можете видеть это, передав секрет в ASCII «123456789» и проверив его против приложения D от http://www.ietf.org/rfc/rfc4226.txt).

Что вам нужно сделать, это конвертировать секрет, который вы ввели в аутентификатор Google из base32 в ASCII.

Вы можете использовать эту утилиту класса Base32 из GitHub https://github.com/devicenull/PHP-Google-Authenticator/blob/master/base32.php сделать преобразование для вас, то просто добавьте в:

include_once "base32.php"; 
$keyToTest = "mysecretvalue"; 

$b = new Base32(Base32::csRFC3548); 
$keyToTest = $b->toString($keyToTest); 

for($i=0;$i<10;$i++){ 
    print $i."\t".($a=oath_hotp($keyToTest,$i)); 
    print "\t".oath_truncate($a)."\n"; 
} 
Смежные вопросы