2014-08-27 4 views
3

서버 측 비밀번호를 사용하여 생성 된 Google 인증 자 토큰을 확인하는 간단한 Perl 구현을 찾고 있습니다. 예를 들어,Perl의 Google 인증 자 구현

다음 구글 URL이 구글 인증 응용 프로그램에서 읽을 수있는 QR 코드로 (비밀이 e4ytonjeim4hcsrhja5fe5kqfu입니다 아래의 경우) base32 형식으로 서버의 비밀을 인코딩 할 수 있습니다 (아래 이미지 참조) : 716340.이 어떻게 토큰의 정확성을 검증 할 : QR 코드는 같은 토큰을 생성하는 OTP 앱으로 스캔하면
https://chart.googleapis.com/chart?cht=qr&chs=100x100&chl=otpauth%3A%2F%2Ftotp%2Fmysite%3A29%3Fsecret%3De4ytonjeim4hcsrhja5fe5kqfu%26issuer%3Dmysite

? 당신의 목적을 위해 Google Authenticator implementation in Python

+2

동일한 질문이 아닙니다. 다른 질문에 OP가 코드를 제공하고 주제에 관한 질문을했습니다. 이 질문은 주제를 벗어났습니다. 파이썬 코드를 번역하려는 시도조차하지 않은 완전한 솔루션이나 외부 리소스를 요구하고 있습니다. 시도가 있고 붙어있는 위치를 설명하는 것을 고려하십시오. –

+0

충분히 공정하십시오. 먼저 완전한 솔루션을 생각해 보면 분명히 게시 할 것이지만 다른 사람들이 이미이 농구대를 뛰어 넘을 수도 있기 때문에 묻고있었습니다. 난 대답 (비록 내가 완전한 대답을 요구하고있어) StackOverflow에 다른 사람들에게 매우 유용한 리소스가 될 것 같아요. 나는 또한 파이썬 사용자가 아니기 때문에 누군가 다른 사람이 즉시 알아낼 수있을 때 문법을 알아 내려고 노력하면서 상당한 시간 낭비 할 것이다. –

답변

5

확인 (희망이 가입한다 이 (Taking the SHA1 HMAC of hex strings in Perl)

다음
#!/usr/bin/perl -w 

use strict; 
use warnings; 

use Convert::Base32; 
use Digest::HMAC_SHA1 qw/ hmac_sha1_hex /; 

my $base_32_secret = "JBSWY3DPEHPK3PXP"; 
print "".totp_token($base_32_secret)."\n"; 

sub totp_token { 
    my $secret = shift; 

    my $key = unpack("H*", decode_base32($secret)); 
    my $lpad_time = sprintf("%016x", int(time()/30)); 
    my $hmac = hmac_sha1_hex_string($lpad_time, $key); 

    my $offset = sprintf("%d", hex(substr($hmac, -1))); 

    my $part1 = 0 + sprintf("%d", hex(substr($hmac, $offset*2, 8))); 
    my $part2 = 0 + sprintf("%d", hex("7fffffff")); 

    my $token = substr("".($part1 & $part2), -6); 
    return $token; 
} 

sub hmac_sha1_hex_string { 
    my ($data, $key) = map pack('H*', $_), @_; 
    hmac_sha1_hex($data, $key); 
} 
3

겠습니까 Auth::GoogleAuthenticator 일 :

이 질문은이 파이썬 질문의 펄과 동일?

편집 : 확실합니다. 이것은 JS에 의해 생성 된 OTP의 유효성을 검사합니다. 카운터가 적시에 더 이상 적절하지 않으면 빈 문자열을 반환합니다. 즉 거짓. 그리고 응용 프로그램의 URL 결과를 사용하면 JS로 동기화되는 :

use Data::Printer; 
use Auth::GoogleAuthenticator; 

my $auth = Auth::GoogleAuthenticator->new(secret_base32 => q/e4ytonjeim4hcsrhja5fe5kqfu/); 
say $auth->registration_url; 
p($auth->verify('252499')); 

출력 : 조금 걸 렸어요하지만 펄 솔루션을 가지고

otpauth://totp/?secret=e4ytonjeim4hcsrhja5fe5kqfu 
1 
+0

이것은 작동하지 않습니다. 이 javascript oauth 예에 대한 비밀을 사용했습니다. http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/ Google 인증 프로그램에서 동일한 토큰을 생성합니다. .그러나 Auth :: GoogleAuthenticator와 동일한 비 밀 번호를 사용하면 일치하는 토큰이 생성되지 않습니다. –

6

그의 도움을 보로딘에 감사합니다 :) 약간 게으른 문제는 다른 해결책, 그리고 당신은에서 생산 토큰을 일치 확인할 수 있습니다 후손을 위해 823,210

use Authen::OATH; 
use Convert::Base32; 
my $oath = Authen::OATH->new(); 
my $secret = "JBSWY3DPEHPK3PXP"; 
my $otp = $oath->totp( decode_base32($secret)); 
print $otp."\n"; 
2

, 나는, 알고리즘을 약간 단순화 비제이의 대답 (감사 친구) @에서 스크립트를했다 TOTP 정의에서 문서를 추가, 일부 샘플 코드를 추가했습니다.

전체 TOTP 2 Factor Auth Perl script
my $paddedTime = sprintf("%016x", int(time()/$TIME_STEP)); 
my $data = pack('H*', $paddedTime); 
my $key = decode_base32($secret); 

# encrypt the data with the key and return the SHA1 of it in hex 
my $hmac = hmac_sha1_hex($data, $key); 

# take the 4 least significant bits (1 hex char) from the encrypted string as an offset 
my $offset = hex(substr($hmac, -1)); 
# take the 4 bytes (8 hex chars) at the offset (* 2 for hex), and drop the high bit 
my $encrypted = hex(substr($hmac, $offset * 2, 8)) & 0x7fffffff; 

# the token is then the last 6 digits in the number 
my $token = $encrypted % 1000000; 
# make sure it is 0 prefixed 
return sprintf("%06d", $token); 

이 Github에서에서 다운로드 할 수 있습니다

내가있는 아래로 깍 수 생성 코드는 비제이의 대답 @ 단지 단순화이다.