Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Google Authenticator with NodeJS

Google Authenticator with NodeJS

Mini-Talk at the first Vienn-NodeJS-Meetup

Avatar for Philipp Dunkel

Philipp Dunkel

March 14, 2014
Tweet

Other Decks in Programming

Transcript

  1. PROTOCOL • T imebased • O ne • T ime

    • P assword RFC 6238 - http://tools.ietf.org/html/rfc6238
  2. PRO - CON/CAVEATS • Variable / Changing • Second Factor

    • Standardised • Added Security • Shared Secret • Raw Secret Stored !
  3. GOOGLE AUTHENTICATOR - IN THE WILD • Amazon Web Services

    • Asia Nexgen • Atomic-Trade.com • App.net • Bitstamp • Bitcoin.de • Blockchain.info • BTC-e.com • CaVirtEx.com • Cex.io • CipherGraph Networks • Coinbase • Dashlane • DigitalOcean • Dreamhost • Dropbox • Drupal • Evernote • Eclipse Mining Consortium • Facebook • Gaia Online • Gandi.net • GitHub • Google Apps • Google Mail • HootSuite • Joomla • LastPass • Linode • LinOTP • LocalBitcoins • Linux • Microsoft account • Mt. Gox • Net4Game • Okcoin • Salesforce.com • Synology • SupportPoint • TACACS.net • Teamviewer • timetotrade • WordPress • Xat • XenForo ! !
  4. CREATE A SECRET var OTP = require(‘otp’); function createUser(request, reply)

    { var otp = OTP({ name: request.params.username + '@demo' }); var filename = __dirname + '/data/' + request.params.username + ‘.json’; var content = JSON.stringify(otp, undefined, ' ‘); fs.writeFile(filename, content, function(err) { if (err) return reply(err); reply(otp.totpURL); }); }
  5. TOTP - INFORMATION { "class": "OTP{@phidelta}", "name": "pipobscure@demo", "keySize": 32,

    "codeLength": 6, “secret": “INJCM5ZXGEYW2QJJGN5TEW25LNAC6NLUFZYWK2CWIE2U2S3MIZIQ“, "epoch": 0, "timeSlice": 30 } otpauth://totp/pipobscure@demo?secret=INJCM5ZXGEYW2QJJGN5TEW25LNAC6NLUFZYWK2CWIE2U2S3MIZIQ
  6. CREATE A QR-CODE otpauth://totp/pipobscure@demo?secret=INJCM5ZXGEYW2QJJGN5TEW25LNAC6NLUFZYWK2CWIE2U2S3MIZIQ var QR = require(‘qrpng’); function fetchQRCode(request,

    reply) { var url = request.query.url; var scale = request.query.scale || 4; QR(url, scale, function(err, png) { if (err) return reply(err); reply(png).type('image/png'); }); }
  7. VALIDATE A CODE function verifyCode(request, reply) { var filename =

    __dirname + '/data/' + request.params.username + ‘.json'; fs.readFile(, 'utf-8', function(err, data) { if (err) return reply(err); var otp = JSON.parse(data, OTP.reviveJSON); ! if (String(otp.totp()) !== String(request.payload)) { return reply({ valid: false }).code(403); } ! reply({ valid: true }); }); }