{"id":547,"date":"2015-08-24T16:57:52","date_gmt":"2015-08-24T21:57:52","guid":{"rendered":"http:\/\/sunapi386.ca\/wordpress\/?p=547"},"modified":"2015-10-28T01:07:46","modified_gmt":"2015-10-28T06:07:46","slug":"qr-authentication-tutorial","status":"publish","type":"post","link":"https:\/\/sunapi386.ca\/wordpress\/qr-authentication-tutorial\/","title":{"rendered":"QR Authentication Tutorial"},"content":{"rendered":"<h1>QR Authentication Tutorial<\/h1>\n<p>Tutorial on how to setup a QR Authentication web server and android app. This documents me trying to replicate the WeChat web login\u00a0process, in two parts:<\/p>\n<ol>\n<li>An android application that reads a QR code and logs in<\/li>\n<li>Building a website that hosts this.<\/li>\n<\/ol>\n<p>The tutorial is written in a sequential fashion, because I&#8217;ll add to this tutorial as I go. All my code is on <a href=\"https:\/\/github.com\/sunapi386\/qrauth\">https:\/\/github.com\/sunapi386\/qrauth<\/a>.<\/p>\n<h1>Motivation<\/h1>\n<p>I came across an interesting way to authenticate users from WeChat Web. Their login process is as follows:<\/p>\n<ol>\n<li>The website has a QR image which the\u00a0users scans\u00a0with his WeChat app.<\/li>\n<li>User clicks &#8220;Log In&#8221; in the WeChat app to authenticate.<\/li>\n<li>User is now logged in.<\/li>\n<\/ol>\n<p>The WeChat website looks like this. A unique QR code is generated each time the website is refreshed.<\/p>\n<p><a href=\"https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/wechatweb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-548 aligncenter\" src=\"https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/wechatweb-266x300.png\" alt=\"WeChat login process\" width=\"266\" height=\"300\" srcset=\"https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/wechatweb-266x300.png 266w, https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/wechatweb-909x1024.png 909w, https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/wechatweb.png 1705w\" sizes=\"auto, (max-width: 266px) 100vw, 266px\" \/><\/a><\/p>\n<h1>Android QR scanner<\/h1>\n<p>First thing I want to do is see what this QR code is. I use a library which reads QR codes (<a href=\"https:\/\/github.com\/dm77\/barcodescanner\">https:\/\/github.com\/dm77\/barcodescanner<\/a>)[1.\u00a0This library recognizes different barcode formats, so instead of using a QR code, I could potentially do authentication using any of these:\u00a0UPC_A, UPC_E,\u00a0EAN_13,\u00a0EAN_8,\u00a0RSS_14,\u00a0CODE_39,\u00a0CODE_93,\u00a0CODE_128,\u00a0ITF,\u00a0CODABAR,\u00a0QR_CODE,\u00a0DATA_MATRIX,\u00a0PDF_417].I\u00a0could have taken a screenshot of the QR code and fed it to an online QR code reader, but I wanted to make an app that lets me authenticate in a similar fashion WeChat does. I made a simple android activity that used the library, based on the tutorial. Here are two examples\u00a0of the QR code content.<\/p>\n<pre>https:\/\/login.weixin.qq.com\/l\/oaW3V0XQpA==\r\nhttps:\/\/login.weixin.qq.com\/l\/lZ-ez97Vdg==\r\nhttps:\/\/login.weixin.qq.com\/l\/4YhG7Q3bBQ==<\/pre>\n<ul>\n<li>The format is QR_CODE.<\/li>\n<li>Type is a URI.<\/li>\n<li>Metadata type H.<\/li>\n<\/ul>\n<p>Metadata type describes\u00a0the amount of\u00a0error correction embedded into the QR code. The 4 levels are:<\/p>\n<ol>\n<li>L \u2013 Approximately 7% error correction<\/li>\n<li>M \u2013 Approximately 15% error correction<\/li>\n<li>Q \u2013 Approximately 25% error correction<\/li>\n<li>H \u2013 Approximately 30% error correction<\/li>\n<\/ol>\n<p>Approximately every 5 minutes a new weblink is generated. I tried generating these QR codes on this <a href=\"http:\/\/www.willmaster.com\/library\/generators\/qr-code-generator.php\">website<\/a> to see if they&#8217;d look the same visually, but with no luck.<\/p>\n<figure id=\"attachment_553\" aria-describedby=\"caption-attachment-553\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/scan2-copy.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-553 size-medium\" src=\"https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/scan2-copy-300x180.jpg\" alt=\"QR generated\" width=\"300\" height=\"180\" srcset=\"https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/scan2-copy-300x180.jpg 300w, https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/scan2-copy-1024x614.jpg 1024w, https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/scan2-copy.jpg 1280w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-553\" class=\"wp-caption-text\">WeChat QR<\/figcaption><\/figure>\n<figure id=\"attachment_552\" aria-describedby=\"caption-attachment-552\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/scan1-copy.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-552 size-medium\" src=\"https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/scan1-copy-300x180.jpg\" alt=\"QR generated\" width=\"300\" height=\"180\" srcset=\"https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/scan1-copy-300x180.jpg 300w, https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/scan1-copy-1024x614.jpg 1024w, https:\/\/sunapi386.ca\/wordpress\/wp-content\/uploads\/2015\/08\/scan1-copy.jpg 1280w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-552\" class=\"wp-caption-text\">Generated QR<\/figcaption><\/figure>\n<p>Although these two images encode the same content, visually it looks different. I have no idea why.<\/p>\n<h1><strong>Website<\/strong><\/h1>\n<p>The website generates a new QR code each time the page is refreshed. Our first goal is to setup a web server. I&#8217;ll go with Rails, reason being I like Ruby and Rails is a good framework. May extend it to something more fun later without doing a rewrite.<\/p>\n<h1>Handshaking Process<\/h1>\n<p>I did some googling and didn&#8217;t find how the handshaking works. There is an <a href=\"http:\/\/www.techrepublic.com\/blog\/it-security\/sqrl-a-new-method-of-authentication-with-qr-codes\/\">article<\/a>\u00a0on an app called SQRL (Secure QR Login), which describes it as:<\/p>\n<blockquote><p>On your phone, a SQRL app would contain a secret 256-bit blob of data. This would be your randomly generated secret code, which is never divulged to anybody else. The QR code itself would contain a URL, including the domain name of the site you&#8217;re trying to connect to. When you scan the code, your app would create a public and private key pair from your master key and the domain name of the site, using an HMAC hashing function. Then, the app would communicate with the site directly, sending the public key as your identity (the equivalent of a username), and the encrypted QR code as your authentication (the equivalent of a password). Since your master code, the secret blob of data, never changes, the resulting public key wouldn&#8217;t change either. That means the website would know it&#8217;s you. And by encrypting the QR code of the site with your private key, the site can verify that you indeed possess the matching private key, without actually having it, thanks to the beauty of public key cryptography.<\/p><\/blockquote>\n<p>Keeping in mind how this works, I came up with the following authentication process.<\/p>\n<ul>\n<li>Keep a secret in the phone app.<\/li>\n<li>The QR encodes a link causes<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>QR Authentication Tutorial Tutorial on how to setup a QR Authentication web server and android app. This documents me trying to replicate the WeChat web login\u00a0process, in two parts: An android application that reads a QR code and logs in Building a website that hosts this. The tutorial is written in a sequential fashion, because &hellip; <a href=\"https:\/\/sunapi386.ca\/wordpress\/qr-authentication-tutorial\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">QR Authentication Tutorial<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[31],"tags":[],"class_list":["post-547","post","type-post","status-publish","format-standard","hentry","category-tutorial"],"_links":{"self":[{"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/posts\/547","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/comments?post=547"}],"version-history":[{"count":5,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/posts\/547\/revisions"}],"predecessor-version":[{"id":555,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/posts\/547\/revisions\/555"}],"wp:attachment":[{"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/media?parent=547"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/categories?post=547"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/tags?post=547"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}