Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Persona: in your browsers, killing your passwords

Persona: in your browsers, killing your passwords

Introduction to Persona, a new cross-browser login system for the web that's built entirely in Javascript. Powered by node.js on the backend, it pushes most of the crypto to the browser in order to create a secure and privacy-sensitive experience.

0110e86fdb31486c22dd381326d99de9?s=128

Francois Marier

November 15, 2012
Tweet

More Decks by Francois Marier

Other Decks in Programming

Transcript

  1. François Marier – @fmarier Persona: in your browsers, killing your

    passwords
  2. Username: francois Password: **************** X Sign in

  3. security

  4. None
  5. None
  6. None
  7. None
  8. None
  9. None
  10. bcrypt

  11. bcrypt per-user salt

  12. bcrypt per-user salt site secret

  13. bcrypt per-user salt site secret password & lockout policies

  14. bcrypt per-user salt site secret password & lockout policies secure

    recovery
  15. bcrypt per-user salt site secret password & lockout policies secure

    recovery 2012 2012 password password guidelines guidelines
  16. None
  17. conversion rate

  18. # hits signup

  19. # hits signup signup_complete

  20. # hits signup signup_complete l o s t cust- omers

  21. existing solutions

  22. client certificates

  23. centralized authorities

  24. None
  25. so... storing passwords is hard

  26. so... storing passwords is hard no suitable alternatives

  27. None
  28. decentralized

  29. privacy-sensitive decentralized

  30. privacy-sensitive simple decentralized

  31. privacy-sensitive simple open source decentralized

  32. in your browser

  33. how does it work?

  34. francois@mozilla.com

  35. getting a proof of email ownership

  36. authenticate?

  37. authenticate? public key

  38. authenticate? public key signed public key

  39. you have a signed statement from your provider that you

    own your email address
  40. None
  41. None
  42. None
  43. None
  44. None
  45. None
  46. None
  47. logging into a 3rd party site

  48. Valid for: 2 minutes wikipedia.org assertion

  49. Valid for: 2 minutes wikipedia.org check audience assertion

  50. Valid for: 2 minutes wikipedia.org check audience check expiry assertion

  51. Valid for: 2 minutes wikipedia.org check audience check expiry check

    signature assertion
  52. assertion Valid for: 2 minutes wikipedia.org public key

  53. assertion Valid for: 2 minutes wikipedia.org

  54. assertion session cookie

  55. achieving that vision

  56. None
  57. email providers browser vendors

  58. email providers

  59. fmarier@gmail.com

  60. fmarier@gmail.com

  61. fallback identity provider: login.persona.org

  62. None
  63. None
  64. None
  65. persona.org account

  66. client-sessions jwcryto computer-cluster nodemailer connect & express uglify bcrypt ejs

    underscore convict winston vows
  67. “A Node.JS Holiday Season” https://hacks.mozilla.org/

  68. proxy identity provider:

  69. support for all email providers

  70. browser vendors

  71. navigator.id.*

  72. None
  73. None
  74. None
  75. js

  76. support for all modern browsers >= 8

  77. None
  78. L I F D

  79. Locally Isolated Feature Domain

  80. wanted: trusted code running in the browser

  81. browserid.org login.persona.org

  82. browserid.org login.persona.org

  83. localStorage localStorage.setItem("key", serializedKey); var serializedKey = localStorage.getItem("key");

  84. storage tied to login.persona.org

  85. window.postMessage()

  86. None
  87. https://login.persona.org localStorage jschannel

  88. jschannel questions? https://login.persona.org localStorage

  89. live demo

  90. using it on your site

  91. None
  92. <script src=”https://login.persona.org/include.js”> </script> </body></html>

  93. navigator.id.watch({ loggedInEmail: “francois@mozilla.com”, onlogin: function (assertion) { $.post('/login', {assertion: assertion},

    function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; } });
  94. navigator.id.watch({ loggedInUser: “francois@mozilla.com”, onlogin: function (assertion) { $.post('/login', {assertion: assertion},

    function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; } });
  95. navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion},

    function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; } });
  96. navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion},

    function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; } });
  97. navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion},

    function (data) { window.location = '/'; } ); }, onlogout: function () { window.location = '/logout'; } });
  98. None
  99. navigator.id.request()

  100. None
  101. None
  102. None
  103. navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion},

    function (data) { window.location = '/'; } ); }, onlogout: function () { window.location = '/logout'; } });
  104. navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion},

    function (data) { window.location = '/home'; } ); }, onlogout: function () { window.location = '/logout'; } });
  105. var request = https.request({ host: 'verifier.login.persona.org', path: '/verify', method: 'POST',

    headers: { 'content-type': 'application/x-www-form-urlencoded', 'content-length': body.length } }, onVerifyResponse);
  106. var request = https.request({ host: 'verifier.login.persona.org', path: '/verify', method: 'POST',

    headers: { 'content-type': 'application/x-www-form-urlencoded', 'content-length': body.length } }, onVerifyResponse); var body = qs.stringify({ assertion: assertion, audience: 'http://123done.org' }); request.write(body); request.end();
  107. var request = https.request({ host: 'verifier.login.persona.org', path: '/verify', method: 'POST',

    headers: { 'content-type': 'application/x-www-form-urlencoded', 'content-length': body.length } }, onVerifyResponse); var body = qs.stringify({ assertion: assertion, audience: 'http://123done.org' }); request.write(body); request.end();
  108. { status: “okay”, audience: “http://123done.org”, expires: 1344849682560, email: “francois@mozilla.com”, issuer:

    “login.persona.org” }
  109. { status: “failed”, reason: “assertion has expired” }

  110. None
  111. None
  112. None
  113. navigator.id.logout()

  114. navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion},

    function (data) { window.location = '/home'; } ); }, onlogout: function () { window.location = '/logout'; } });
  115. None
  116. 1. load javascript library

  117. 1. load javascript library 2. setup login & logout callbacks

  118. 1. load javascript library 2. setup login & logout callbacks

    3. add login and logout buttons
  119. 1. load javascript library 2. setup login & logout callbacks

    3. add login and logout buttons 4. verify proof of ownership
  120. framework / CMS plugins Express Jungles Mootools Olives Passport

  121. To learn more about Persona: https://login.persona.org/ http://identity.mozilla.com/ https://developer.mozilla.org/docs/Persona/Why_Persona https://developer.mozilla.org/docs/Persona/Quick_Setup https://github.com/mozilla/browserid-cookbook

    https://developer.mozilla.org/docs/Persona/Libraries_and_plugins http://123done.org/ https://hacks.mozilla.org/category/a-node-js-holiday-season/ @fmarier http://fmarier.org
  122. © 2012 François Marier <francois@mozilla.com> This work is licensed under

    a Creative Commons Attribution-ShareAlike 3.0 New Zealand License. Top 500 passwords: http://xato.net/passwords/more-top-worst-passwords/ Parchment: https://secure.flickr.com/photos/27613359@N03/6750396225/ Elephant in room: https://secure.flickr.com/photos/bitboy/246805948/ Beach flower: https://secure.flickr.com/photos/vwingate/4696429215/ Cookie on tray: https://secure.flickr.com/photos/jamisonjudd/4810986199/ Photo credits: