{"id":761,"date":"2015-12-08T08:25:03","date_gmt":"2015-12-08T08:25:03","guid":{"rendered":"http:\/\/adriangrigoras.com\/blog\/?p=761"},"modified":"2016-12-08T08:25:42","modified_gmt":"2016-12-08T08:25:42","slug":"perl-google-authenticator","status":"publish","type":"post","link":"https:\/\/adriangrigoras.com\/blog\/perl-google-authenticator\/","title":{"rendered":"Perl and Google Authenticator"},"content":{"rendered":"<p>In this article I&#8217;ll explain (with code) how to <em>create<\/em> and <em>validate<\/em> a Google Authenticator two-step authentication token, using Perl. Both on the command-line and on a simple website.<\/p>\n<h1 id=\"somebackground\">Some background<\/h1>\n<p>Google Authenticator is a two-step authentication process created by Google. It&#8217;s software based, unlike those hardware tokens your bank may use, and when paired with a service it provides a six digit number which must be used alongside one&#8217;s credentials to log in to a service which requires use of it.<\/p>\n<p>Google provides software versions of the Authenticator for iOS, Blackberry, Android, and a number of other platforms, including &#8220;native&#8221; Windows executables, or even HTML5 web applications.<\/p>\n<p>Google generates an 80-bit secret key for each user, saves it, and then displays it (encoded in base32) to the user in the form of a QR code. The user can then use their mobile application to input it, and use the generated six-digits to authenticate from then onwards.<\/p>\n<p>The application &#8220;simply&#8221; creates a HMAC-SHA1 using the secret key, using the &#8220;number of 30-seconds periods elapsed since the Epoch&#8221; as the message. A part of this is extracted and converted to the six-digit code.<\/p>\n<h1 id=\"howdoicreateagoogleauthenticatorsecret\">\u00a0How do I create a Google Authenticator secret?<\/h1>\n<p>At its most basic, the &#8220;secret&#8221; comprises of 10 bytes from \/dev\/urandom. That&#8217;s it. For more security, one would want to get more than just 10 bytes. Say, 50:<\/p>\n<pre>my $len_secret_bytes = 50;\r\nopen my $RNG, '&lt;', '\/dev\/urandom'\r\n  or die \"Cannot open \/dev\/urandom for reading: $!\";\r\nsysread $RNG, my $secret_bytes, $len_secret_bytes\r\n  or die \"Cannot read $len_secret_bytes from \/dev\/urandom: $!\";\r\nclose $RNG\r\n  or die \"Cannot close \/dev\/urandom: $!\";<\/pre>\n<p>Since you will want to have users input the secret data in the Authenticator application, or have them snap a picture of the QR code to input it in the application, you&#8217;ll have to convert those <tt>$secret_bytes<\/tt> to Base32:<\/p>\n<pre>use Convert::Base32;\r\nmy $secret_base32 = encode_base32( $secret_bytes );<\/pre>\n<p>You will want to save that <tt>$secret_base32<\/tt> somewhere like in a database (next to the &#8220;password_bcrypt&#8221; for the user), or in a flat file (in ~\/.google_authenticator) that is user-specific, since you and your users will want to have it handy: without it, you won&#8217;t be able to verify their six-digit code, and they won&#8217;t be able to either.<\/p>\n<h2 id=\"displayingtheqrcode\">\u00a0Displaying the QR code<\/h2>\n<p>Now you have the <tt>$secret_base32<\/tt>. You can just display that to the users, and they&#8217;ll be able to manually enter it on the Google Authenticator app.<\/p>\n<p>Or, you can have that displayed as a nice QR code they can simply take a picture of, and the app will add the account for them. To do that, you will just need two things: the <tt>$secret_base32<\/tt> code you have already generated for the user, and a <tt>$label<\/tt> you want your users to associate with that secret, for example <tt>foo@example.com on Your Website<\/tt>.<\/p>\n<pre>use URI::Escape;\r\nmy $url   = sprintf(\"otpauth:\/\/totp\/%s?secret=%s\", $label, $secret_base32);\r\nmy $qr_url = sprintf(\"https:\/\/www.google.com\/chart?chs=200x200\" .\r\n    \"&amp;chld=M|0&amp;cht=qr&amp;chl=%s\", uri_escape($url));<\/pre>\n<p>You can then embed that QR code URL inside an <tt>&lt;img&gt;<\/tt> tag and your users will be able to easily add the Google Authenticator secret you have generated for them to their app.<\/p>\n<h1 id=\"howtoauthenticateusers\">\u00a0How to authenticate users<\/h1>\n<p>You have generated a Google Authenticator code for a user, they have added it to their app via a QR code, and now they&#8217;d like to&#8230; use it!<\/p>\n<p>Once you have a user&#8217;s <tt>$secret_base32<\/tt> you can check whether the <tt>$given_token<\/tt> they give you is the correct one, in which case you can continue on checking their password, or not:<\/p>\n<pre>use Authen::OATH;\r\nuse Convert::Base32;\r\nmy $correct_token = make_token_6(\r\n    Authen::OATH-&gt;new-&gt;totp(\r\n        decode_base32( $secret_base32 )\r\n    )\r\n);\r\n$given_token = make_token_6($given_token);\r\n\r\nif ($given_token eq $correct_token) {\r\n    print \"Yup!\"\r\n    #\u00a0Check password, etc.\r\n} else {\r\n    print \"Nope!\"\r\n}\r\n\r\nsub make_token_6 {\r\n    my $token = shift;\r\n    while (length $token &lt; 6) {\r\n        $token = \"0$token\";\r\n    }\r\n    return $token;\r\n}<\/pre>\n<p>The above method will only authenticate users against the <em>current<\/em> value shown on their Google Authenticator. If their device&#8217;s clock (or your server&#8217;s clock) drifts too much, they may have problems authenticating against your server.<\/p>\n<p>If you&#8217;re comfortable enough with a 30-seconds drifting either way, you can look into the following optional parameter for <tt>-&gt;totp<\/tt>:<\/p>\n<pre>my $otp = $oath-&gt;totp( $secret [, $manual_time ] );<\/pre>\n<p>You will then be able to compute:<\/p>\n<pre>my @possible_tokens =\r\n    map { $oath-&gt;totp($secret, $_) }\r\n        time-30, time, time+30;<\/pre>\n<p>And check either of <tt>@possible_tokens<\/tt> against the <tt>$given_token<\/tt>.<\/p>\n<h1 id=\"conclusions\">\u00a0Conclusions<\/h1>\n<p>If you have read through this article, you should now be able to use Perl and the CPAN to:<\/p>\n<ul>\n<li>Create a secure Google Authenticator &#8220;secret&#8221;, and store it per-user<\/li>\n<li>Display the &#8220;secret&#8221; so your users can easily import it on their app<\/li>\n<li>Authenticate your users against the known secret<\/li>\n<\/ul>\n<p>Here&#8217;s to hoping this article will help make websites written in Perl just that bit more secure!<\/p>\n<p>source:\u00a0https:\/\/blog.darkpan.com\/article\/6\/Perl-and-Google-Authenticator.html<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article I&#8217;ll explain (with code) how to create and validate a Google Authenticator two-step authentication token, using Perl. Both on the command-line and on a simple website. Some background Google Authenticator is a two-step authentication process created by Google. It&#8217;s software based, unlike those hardware tokens your bank may use, and when paired\u2026 <span class=\"read-more\"><a href=\"https:\/\/adriangrigoras.com\/blog\/perl-google-authenticator\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[],"class_list":["post-761","post","type-post","status-publish","format-standard","hentry","category-perl"],"_links":{"self":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts\/761","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/comments?post=761"}],"version-history":[{"count":1,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts\/761\/revisions"}],"predecessor-version":[{"id":762,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts\/761\/revisions\/762"}],"wp:attachment":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/media?parent=761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/categories?post=761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/tags?post=761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}