-
Notifications
You must be signed in to change notification settings - Fork 11
Webcrypto API #7
Comments
I started looking into a webcrypto implementation (so far without fallbacks). I got the unit test level to The jwk public key can be considered invalid if one shares the understanding of the spec as currently implemented by Chrome The problem is the key's modulus value (n) which converted to a number has leading zeros.
This causes Chromes webcrypto implementation to issue DOMException: The JWK "n" member contained a leading zero.`. This lead me to this issue in rsa-pem-to-jwk and then to this Chrome Issue 383998: Reject JWK which use non-minimal octet representation for big integers When I adjust the modulus of the test key by dropping the leading It appears this is no longer (or never has been) an issue in pem-jwk which is used by our connect server's key generation. See issue dannycoates/pem-jwk#2 for a test case. @christiansmith: Do you know how the test key came to be? Is it ensured that jwk delivered by the connect server will not have this issue? |
@henrjk – good find on the modulus value! I don't recollect the origins of the key. It's been quite a long time since initially writing this code. In light of your discovery, we should verify that the server is publishing well-formed JWKs. Since originally posting this issue, it's been suggested that we consider using https://github.com/cisco/node-jose under the hood for all things JWT in both the client and the server code. That library works in both node and the browser and uses WebCrypto API "where feasible". It doesn't cover some of the additional OIDC requirements, so there's still a need for much of the logic in https://github.com/anvilresearch/connect-jwt, at least on the server side. @msamblanet and @bettiolo might have some helpful input on this idea. We can discuss all this at the hangout on Thursday if you're able to make it. |
@christiansmith I cannot join you today as I am pretty busy at work. While implementing my OAuth 1.0 signature generation library I inlined in the client side bundle Google's crypto-js. I am using jsonwebtoken pretty much everywhere. Pretty much the standard stuff. |
@christiansmith Sorry for the late notice, I will not make it to todays hangout. To me the crypto stuff makes less sense if it is not done natively. I could see us providing several choices:
I am currently exploring 2, the webcrypto only implementation. The units tests so far pass on the following browsers: INFO [Safari 9.0.2 (Mac OS X 10.10.5)]
INFO [Firefox 43.0.0 (Mac OS X 10.10.0)]
INFO [Chrome 47.0.2526 (Mac OS X 10.10.5)]
INFO [Edge 13.10586.0 (Windows 10 0.0.0)]
INFO [IE 11.0.0 (Windows 7 0.0.0)] I have not yet tested against recent mobile platforms and also haven't done manual testing against the connect server. I am currently less interested in working on a fallback solution although I'd be happy to learn more about node-jose. At first glance it looks pretty heavy weight for the browser side. |
I am aiming to have this module use only webcrypto.
This project would implement these adaptors using the webcrypto API. It would also have an API to allow overriding these either replacing or as fallback with custom implementations. There would be additional modules to implement these like code that is currently in master. |
I am thinking to have us publish this module as npm CJS module intended to run inside a browser. The npm module code would be ES5 code while I am having the implementation sources in ES6. |
@henrjk it's really important that we start reviewing and discussing this work. This area particularly requires extra eyes and healthy debate. Crypto is dangerous to "them" used correctly and dangerous to us(ers) if not. Complicating the matter, as I understand it there's not a great deal of support for WebCrypto API among cryptographers. Can you give us a first look at the hangout tomorrow? |
I pushed the latest code to my fork at https://github.com/henrjk/connect-js/tree/webcrypto.
Now the main file for which a prior version is in master is in anvil-connect.js. Crypto related tests are in All links here go to master so may shift as new commits are made. @christiansmith and all. I'd be happy to go over this tomorrow in the hangout. Also I am curios to learn more about why there is no support for the WebCrypto API from cryptographers and whether there are better alternatives. |
@henrjk thanks for the code review in the hangout. This is great work! Look forward to testing it out. |
😢 that I missed it |
I have updated code at This code is now in a state that is (hopefully) pretty close to being done. However currently token claims are not verified. This is something I wanted to look into also. Aside from that it should be good for testing it out. I also have an updated example fork at https://github.com/henrjk/connect-example-angularjs/commits/use-npm . The readme has a section Get connect-js client libraries which should help getting the example consumed. Anyone who is consuming this, please let us know any issues you encounter and also if things just worked. Thank you! |
I wanted to mention that I have created two projects which contains an iteration of the crypto code currently used in the master branch of connect-js. They are:
They can be used by an app which must run on browsers not supporting subtle.crypto (after shimming). |
I updated the code: https://github.com/henrjk/connect-js/tree/webcrypto The updated example version will not work with the earlier connect-js version. The connect-js library is now only dependent on angular (and q) for its tests. Comments welcome! |
@henrjk this all looks excellent at first glance. Look forward to trying it out. Are you still free for pairing early next week? Monday or Tuesday should work for me. |
Just updated both connect-js and connect-example-angularjs forks with some changes based on our pairing yesterday. Changes in connect-js were to:
For connect-example-angularjs the following changes were made:
I looked a bit into the rp/op session management and it is not perfectly working at the moment. Is this supposed to also work if you use a different browser such Firefox and Chrome? I think this version could be used for more testing from interested parties. |
Awesome. I plan to give this a try...I'm hoping this week. I'll drop any input in here or gitter if I run into issues. |
@tomkersten don't hesitate trying to reach me. I just pushed a small improvement for register_with_anvil_connect.sh improve nvl error reporting to have better reporting when registration does not work. I might continue pushing small changes like this as I discover issues. |
pushed changes relating to make popup authorization work in both |
Updated example readme |
@henrjk thanks for all your hard work on this. I look forward to merging the eventual PR! Before we do that, it will be great to have feedback from users of the current release. Please everyone, give @henrjk's fork a try and let us know how it works for you. Thanks @tomkersten. @hedleysmith, you might be interested as well (the fork works with npm). |
I just pushed changes so that session management work in both With work I mean that you can now open two windows with the example in a browser and then when the login state changes the other window properly reacts as well. |
I'm pretty sure this depends on localStorage/cookies so it would be Pretty sure. 😉 -tom On Wed, Feb 3, 2016, at 10:02 PM, Henrich Kr�mer wrote:
|
Thx! That's what I thought. But wanted to double check... |
The OpenID Connect session management defines how to monitor the End-User's login status at the OpenID Provider on an ongoing basis so that the Relying Party can log out an End-User who has logged out of the OpenID Provider. Within a single browser the session management between multiple tabs/windows works solely using localStorage events at the moment. I validated this by commenting out the creation of the OP and PP frames used for OIDC session management and this continued to work. I tried whether an OIDC session management event is generated when tokens expire but did not see this happening. Unless there are cases where OIDC session management state changes would be triggered we should probably disable the RP/OP iframes as we can't really test them. |
@henrjk – @tomkersten is right, this is browser specific. I also think we don't want to link sessions between browsers. The OIDC Session spec is among the most frustrating specifications I have ever worked with. It's not even entirely clear about it's purpose. The main utility, IMO, even though it's framed up as "log out an End-User on the RP who has logged out of the OpenID Provider", is single sign-on between multiple hosts/RPs. The localStorage events you're referencing are something unique to Anvil, it's our way of getting that real-time feeling SSO between different Relying Parties (and coincidentally multiple tabs with the same app). It's outside the scope of the spec. Without our enhancements, changes in login state would only be apparent between page loads. That doesn't work particularly well for SPAs. We should pair on this particular subject because it's not well documented, horribly specified, and definitely one of the darker corners of the code. |
@henrjk I [finally] got around to trying this out (sorry for delay), but am running into a silly issue that I can't quite figure out... I've downloaded your fork, built, and link it in Any thoughts? |
I have @henrjk's fork working locally with an Aurelia application and it looks great. The API is nice and the code reads great. I have not done extensive testing with it, but the authentication against an existing provider works as I would expect. I will throw a few more scenarios as it, but for now, it's looking good. |
@christiansmith asked me to prepare a PR for this at https://github.com/anvilresearch/connect-js/tree/webcrypto-api and perhaps also for the example. I'd prefer to base these PRs on a cleaned up commit history for the following two branches:
Has anyone made changes based on the commits in the branches above (which are not in the origin)? |
This adopts usage of the WebCrypto Api based connect-js library as tracked on anvilresearch/connect-js#7 (comment) With this most API methods are now returning promises. Summary of other changes: * Use npm and browserify to consume connect-js * Adopt latest anvil cli The changes were made over a period of time. Here are some of the more notable original commits with comments: COMMIT: callback_popup to check whether opener is available COMMIT: index.html shows userInfo.name may not be available COMMIT: add APP_AUTH_CALLBACK variable COMMIT: establish scope.session in SigninCtrl and MainCtrl COMMIT: scope to requireScope profile instead of realm COMMIT: adopt new cli COMMIT: Handle disconnected popup in passwordless login. The passwordless login method sends the user a link in an email. When the user follows this link a new browser window opens. However the original popup window will not redirect and remains open with a page allowing to resend the link. The connect-js library was changed to handle this case so that it would expect the page which is opened when the email link is followed to handle the callback so that the session is populated appropriately in localStorage. connect-js now listens for that and then closes the popup window. It also expect the email page to close itself. This may not work for all browsers. I did see this work in Chrome and Safari but fail in Firefox. Note that the popup Callback should behave in the same way it it is redirected by the server, which happens when other authentication methods are used. This also adds the newer dependencies and improves logging similar to how it was done in connect-js. COMMIT: refresh angular app on passwordless login COMMIT: adding jspm bundle-sfx for demo COMMIT: Manual angular bootstrap This was to avoid issue systemjs/systemjs#1032 COMMIT: Switch to using npm and browserify This now requires anvil-connect-js ^0.2 bower is still used for shims and bootstrap. Some bugs were addressed found during manual testing. Also added more logging using bows. COMMIT: Added section Get connect-js client libraries I am uncertain about the remainder of the doc, but it looked OK to me at first glance although I have not done a client registration for quite some time.
Section github-rate-limits describes the changes I did in my fork to make the travis build pass. In a nutshell:
|
@henrjk - I've been looking through your work on porting connect-js to use native webcrypto, at the
|
Oh, one more question - what is |
@dmitrizagidulin let me address your question 2 first. webcrypto-shim Readme has more details about the supported browsers. IE implemented crypto primitives with a different API. The shim provides an adapter so that IE 11 can then be used with the webcrypto API. The adapter code is not actually implementing any crypto primitives and is simply a thin layer. From the web-crypto shim readme: These browsers have unprefixed and conforming webcrypto api implementations, so no need in shim: This comment way up lists browser version I have tested with. This looked all good to me. Now while the tests are using the shim it is not part of the connect-js library. Users of the library can decide to use the shim or not. The example connect-example-angularjs/index.html for example does include the shim. I will answer your other questions separately hopefully later today. |
re webcrypto-shim -- makes sense, thank you! |
Regarding your bows question: "Do you think it would be possible to have bows be an optional dependency (maybe via dependency injection)? So that devs who want to use it can init & pass it in, and those that don't can use something built-in like I investigated a bit about using optional dependencies for supporting fallback legacy crypto libraries under jspm and have a bunch of references of various discussions. For example here. Bows uses andlog which uses
Ultimately this allows to not having to remove log statements from source which I prefer. What I liked about bows is mostly that one can add a 'module' prefix in a simple way to each log statement in the code. Also bows offers levels such as debug, error and more. I found it useful in a few cases to mark things as more than debug. Ultimately I view the logging code only useful for development. @dmitrizagidulin Do you have a broader use case for logging in mind? Does this make sense to you? |
I don't necessarily have a broader use case in mind, as far as logging. I'm only asking about it because it's a dependency we're bundling that's not part of the core functionality, seems to be a developer nicety. |
Although logging here is mostly a development concern, at least until webcrypto implementations mature, one might want to ensure/require that logging is available so that users can switched it on for troubleshooting. So I am not certain that making it optional at this stage would be the best. However if others feel this should be optional I would not object. However I can't promise to have the cycles to investigate how to do this at the moment. I am not fixated on bows in particular although I found it nice to work with. Here is some more data about # The bows dist folder has andlog embedded
[email protected] dev (webcrypto2)$ wc dist/*.js
143 451 4516 bows.js
2 66 2524 bows.min.js
[email protected] dev (webcrypto2)$ wc andlog.js
29 92 837 andlog.js While it would probably good enough to use andlog instead of bows. I am not sure whether this makes much of a difference as there would still be a dependency. |
@dmitrizagidulin regarding tiny-emitter. This was introduced in commit f0f062f (see 'Handle disconnected popup in passwordless login' for more details). This library supports asking credentials in a popup window. With a normal login this window redirects to a callback which then closes its parent window. You can search for Note that passwordless login has not been pulled in yet. |
Got it, thanks :) (Btw, I really appreciate you answering these 'why' questions, it's very helpful!) One more - what's the difference between |
Yes, I really appreciate your questions as well. text-encoder-lite encodes/decodes UTF-8 to/from a byte array. There is a section about UTF-8 encoding/decoding in connect-js/devnotes.md. |
Ah, I see. And what are your thoughts on using https://github.com/inexorabletash/text-encoding instead of |
@dmitrizagidulin Why jspm not webpack or browserify? I would think that all these tools could be made to work in this context. jspm's ES6 support looked most compelling to me and in particular it seemed using ES6 modules might be the future. |
https://github.com/inexorabletash/text-encoding is much larger because it supports many encodings we don't need. |
I think |
I did not perceive the on demand loading as a problem during development. However I don't think that folks currently would use on demand loading in production and instead have jspm generate a single or a view bundles. This module should definitely not impose consumers to having to use jspm, webpack, browserify or anything else. In addition one could release a script bundle. This bundle can be created with @dmitrizagidulin Does this lessen your concerns? |
@henrjk I would still prefer not to use |
We've experimented with a number of JavaScript crypto libraries (sjcl, crypto-js, jsrsasign, etc) in this package for various purposes. The most important case is verifying signatures. In the meantime, the WebCrypto API has been maturing and will eventually be ready to replace some or all of these dependencies.
We need to explore the potential for rewriting some of this code using WebCrypto, take stock of it's readiness for general use, and consider implementing fallbacks for older browsers that will continue to require polyfills or additional optional dependencies.
The text was updated successfully, but these errors were encountered: