{"id":620,"date":"2018-06-20T15:55:54","date_gmt":"2018-06-20T23:55:54","guid":{"rendered":"http:\/\/unmitigatedrisk.com\/?p=620"},"modified":"2018-06-23T13:08:42","modified_gmt":"2018-06-23T21:08:42","slug":"what-is-fortify-and-how-does-it-work","status":"publish","type":"post","link":"https:\/\/unmitigatedrisk.com\/?p=620","title":{"rendered":"What is Fortify and how does it work?"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">If you follow the W3C or web development, you probably know that the <a href=\"https:\/\/www.w3.org\/TR\/WebCryptoAPI\/\">WebCrypto API<\/a><\/span><span style=\"font-weight: 400;\">\u00a0was designed to provide fairly low-level cryptographic algorithms so that you could build web applications that interoperate with existing systems. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">The idea being it was largely the cryptographic primitives that needed to be implemented natively and that the other layers of interoperability could be handled in pure Javascript when combined with good application security practices and new features like <a href=\"https:\/\/www.w3.org\/TR\/SRI\/\">SRI<\/a><\/span><span style=\"font-weight: 400;\">. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">While there are <a href=\"https:\/\/tonyarcieri.com\/whats-wrong-with-webcrypto\">legitimate concerns over the use of cryptography in browser-based applications<\/a><\/span><span style=\"font-weight: 400;\">\u00a0there are also legitimate uses. Afterall who doesn&#8217;t like to watch a film on Netflix now and again without having to run Flash?<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For another example of an application that makes heavy use of WebCrypto take a look at <a href=\"https:\/\/1password.com\/\">1Password<\/a><\/span><span style=\"font-weight: 400;\">\u00a0which is one of the most popular password managers in use today. They use WebCrypto and the same origin security model of browsers to allow them to help manage their passwords locally and store the associated ciphertext on their servers.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The utility of WebCrypto does not end with applications though, many libraries, some by my company, Peculiar Ventures, leverage this raw cryptographic capability to make it easier for others to build applications that interoperate with their counterparts on other platforms. For example consider <a href=\"https:\/\/github.com\/PeculiarVentures\/PKI.js\">PKIjs<\/a><\/span><span style=\"font-weight: 400;\">,\u00a0 <a href=\"https:\/\/github.com\/PeculiarVentures\/xmldsigjs\">XMLDSIG<\/a><\/span><span style=\"font-weight: 400;\">, <a href=\"https:\/\/github.com\/PeculiarVentures\/xadesjs\">XADESjs<\/a><\/span><span style=\"font-weight: 400;\">, <a href=\"https:\/\/github.com\/PeculiarVentures\/2key-ratchet\">2key-ratchet<\/a><\/span><span style=\"font-weight: 400;\">\u00a0and <a href=\"https:\/\/github.com\/square\/js-jose\">js-jose<\/a><\/span><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">However powerful this new native cryptographic capability is, it intentionally left out providing access to local cryptographic certificates and key stores as well opted out of providing web applications access to smart cards and other security elements. I personally both agree with these decisions and understand why they were made but that is something for another post. With that said, that doesn&#8217;t mean those capabilities are not useful and that is where <a href=\"https:\/\/fortifyapp.com\">Fortify<\/a><\/span><span style=\"font-weight: 400;\">\u00a0comes in.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">So what is Fortify?<\/span><\/h2>\n<p><a href=\"https:\/\/fortifyapp.com\"><span style=\"font-weight: 400;\">Fortify<\/span><\/a><span style=\"font-weight: 400;\">\u00a0is a client application that you install that runs in the background as a tray application in Windows, OSX, and Linux that provides these missing capabilities to authorized applications.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">It does this by binding to 127.0.0.1 and listening to a high-order well-known port for incoming requests. Browsers allow web applications to initiate sessions to this address, over that session a <a href=\"https:\/\/fortifyapp.com\">Fortify<\/a><\/span><span style=\"font-weight: 400;\">\u00a0enabled application establishes a secure session and if approved by the user is allowed to access these missing capabilities.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">How is this secure session established?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">At the core of\u00a0<a href=\"https:\/\/fortifyapp.com\">Fortify<\/a><\/span><span style=\"font-weight: 400;\">\u00a0is a library called <a href=\"https:\/\/github.com\/PeculiarVentures\/2key-ratchet\">2key-ratchet<\/a><\/span><span style=\"font-weight: 400;\">. This implements a `Double Ratchet` protocol similar to what is used by <a href=\"https:\/\/signal.org\">Signal<\/a><\/span><span style=\"font-weight: 400;\">. In this protocol each peer has an identity key pair, we use the public keys from each participant to compute a short numeric value since in the protocol the peers prove control of the respective private keys we know that once the keys are authenticated we are talking to the same \u201cidentity\u201d.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Since <a href=\"https:\/\/github.com\/PeculiarVentures\/2key-ratchet\">2key-ratchet<\/a><\/span><span style=\"font-weight: 400;\">\u00a0uses WebCrypto we leverage the fact that keys generated in a web application are bound to the same origin, we also (when possible) utilize non-exportable keys to mitigate the risks of these approved keys from being stolen.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This gives us an origin bound identity for the web application that the Fortify client uses as the principal in an Access Control List. This means if you visit a new site (a new origin), even if operated by the same organization, you will need to approve their access to use Fortify.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For good measure (and browser compatibility) this exchange is also performed over a TLS session. At installation time a local CA is created, this CA is used to create an SSL certificate for 127.0.0.1. The private key of the CA is then deleted once the SSL certificate is created and the Root CA of the certificate chain is installed as a locally trusted CA. This prevents the CA from being abused to issue certificates for other origins.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">What happens over this session?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">The protocol used by <a href=\"https:\/\/fortifyapp.com\">Fortify<\/a><\/span><span style=\"font-weight: 400;\">\u00a0use a <a href=\"https:\/\/tools.ietf.org\/html\/rfc5785\">\/.wellknown\/<\/a><\/span><span style=\"font-weight: 400;\">\u00a0(not yet registered) location for capability discovery. The core protocol itself is <a href=\"https:\/\/en.wikipedia.org\/wiki\/Protocol_Buffers\">Protobuf based<\/a><\/span><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">We call this protocol <a href=\"https:\/\/github.com\/PeculiarVentures\/webcrypto-local\">webcrypto-socket<\/a><\/span><span style=\"font-weight: 400;\">. You can think of the protocol as a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Remote_procedure_call\">Remote Procedure Call or (RPC)<\/a><\/span><span style=\"font-weight: 400;\">\u00a0to the local cryptographic and certificate implementations in your operating system.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Architecturally what does the client look like?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">The <a href=\"https:\/\/fortifyapp.com\">Fortify<\/a> client is a <a href=\"https:\/\/nodejs.org\">Node.js<\/a><\/span><span style=\"font-weight: 400;\">\u00a0application based on <a href=\"https:\/\/electron.atom.io\/\">Electron<\/a> and it accesses all cryptographic implementations via <a href=\"https:\/\/github.com\/PeculiarVentures\/node-webcrypto-p11\">node-webcrypto-p11<\/a><\/span><span style=\"font-weight: 400;\">. This library was designed to provide a WebCrypto compatible API to <a href=\"https:\/\/nodejs.org\/\">Node.js<\/a><\/span><span style=\"font-weight: 400;\">\u00a0applications but it also extends the WebCrypto API to provide basic access to certificate stores.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The <a href=\"https:\/\/fortifyapp.com\">Fortify<\/a><\/span><span style=\"font-weight: 400;\">\u00a0client uses another Peculiar Ventures project called <a href=\"https:\/\/github.com\/PeculiarVentures\/pvpkcs11\">PVPKCS11<\/a><\/span><span style=\"font-weight: 400;\">\u00a0to access the OSX KeyStore, Mozilla NSS or Windows CryptoAPI via this PKCS#11 wrapper.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">It also uses <a href=\"https:\/\/github.com\/santigimeno\/node-pcsclite\">pcsclite<\/a><\/span><span style=\"font-weight: 400;\">\u00a0to listen for a smart card or security token insertions and removals, when new insertions are detected it inspects the ATR of the card. If it is a known <a href=\"https:\/\/github.com\/PeculiarVentures\/webcrypto-local\/blob\/master\/json\/card.json\">card<\/a><\/span><span style=\"font-weight: 400;\">\u00a0the client attempts to load the PKCS#11 library associated with the card. If that succeeds events in the `webcrypto-socket` protocol are used to let the web application know about the availability of the new cryptographic and certificate provider.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Ironically, despite the complication of the PKCS#11 API, this approach enables the code to maintain a fairly easy to understand structure.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The application also includes a tray application that is used to help with debugging, access a test application and manage which domains can access the service.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">So what can I do with it?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">In the simplest case, you can think of Fortify as a replacement for the <a href=\"https:\/\/security.stackexchange.com\/questions\/106257\/alternatives-to-htmls-deprecated-keygen-for-client-certs\">&lt;keygen&gt; tag<\/a><\/span><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Since the client SDK that implements the `webcrypto-socket` protocol is a superset of WebCrypto, with slight modifications, if you have an web application that uses WebCrypto you can also use locally enrolled certificates and\/or smart cards.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Some of the scenarios we had in mind when building the Fortify client included:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&#8212; Enrolling for X.509 certificates over the web,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&#8212; Signing and encrypting\/decrypting email or documents,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&#8212; Building certificate-based authentication schemes with a modern user experience.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Can I use this today?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Yes, it is feature complete and ready for you to take a look.<\/span><\/p>\n<p>There are some examples on\u00a0its usage <a href=\"https:\/\/github.com\/PeculiarVentures\/fortify-examples\">here<\/a>\u00a0and you can find the documentation <a href=\"https:\/\/peculiarventures.github.io\/webcrypto-local\/docs\/\">here<\/a>.<\/p>\n<p><span style=\"font-weight: 400;\">It works on Windows 7+, OSX 10.12+, and Debian based Linux distributions, it also works on IE11, Edge, Safari, Chrome, and Firefox.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In general, you should consider this initial release of a Beta quality, for example I know we need to do additional testing with smart cards and make sure we have the metadata for each card so they work on each supported platform. Otherwise, we expect it to work largely as expected.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Is it Open Source?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Yes, all Peculiar Ventures related libraries to-date have been licensed as BSD or MIT and this is no different so you are free to do with them as you see fit.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">What&#8217;s next?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Over the next year, we will gain enough confidence in the solution to declare it complete. We will also look at adding other useful like smart card password changes and unblocking at some point in the future.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Other than that, we are just looking for your feedback so we can refine the quality of the solution.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Thanks<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">I want to thank the members of the <a href=\"https:\/\/casecurity.org\/\">CASC<\/a><\/span><span style=\"font-weight: 400;\">\u00a0for their support of this project and the many individuals from <a href=\"https:\/\/twitter.com\/\">Twitter<\/a>\u00a0<\/span><span style=\"font-weight: 400;\">who provided feedback and testing.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you follow the W3C or web development, you probably know that the WebCrypto API\u00a0was designed to provide fairly low-level cryptographic algorithms so that you could build web applications that interoperate with existing systems. The idea being it was largely the cryptographic primitives that needed to be implemented natively and that the other layers of [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"footnotes":""},"categories":[12,3],"tags":[],"class_list":["post-620","post","type-post","status-publish","format-standard","hentry","category-programming","category-security"],"_links":{"self":[{"href":"https:\/\/unmitigatedrisk.com\/index.php?rest_route=\/wp\/v2\/posts\/620","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unmitigatedrisk.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unmitigatedrisk.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unmitigatedrisk.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/unmitigatedrisk.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=620"}],"version-history":[{"count":0,"href":"https:\/\/unmitigatedrisk.com\/index.php?rest_route=\/wp\/v2\/posts\/620\/revisions"}],"wp:attachment":[{"href":"https:\/\/unmitigatedrisk.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=620"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unmitigatedrisk.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=620"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unmitigatedrisk.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=620"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}