Giter Site home page Giter Site logo

anvilresearch / jose Goto Github PK

View Code? Open in Web Editor NEW
25.0 12.0 7.0 492 KB

JSON Object Signing and Encryption for Node.js and the browser

License: MIT License

JavaScript 100.00%
jwk cryptographic-algorithms webcrypto encryption json jwt jwe jws signing jose

jose's People

Contributors

christiansmith avatar dmitrizagidulin avatar eternaldeiwos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jose's Issues

Fix support for JWT.encode() with alg: 'none'

Currently, we have entries like supportedAlgorithms.define('none', 'sign', {}) in the algorithms registry, so when you try JWT.encode() where header: { alg: 'none' }, it throws a 'that's not a function' error.

Implement custom format extension regexps (or move to own repo?)

Implement the custom format extensions used in the schemas:

  • StringOrURI
  • NumericDate
  • URI
  • url
  • base64
  • base64url
  • MediaType

Better yet, I think they should be moved upstream to json-document and defined there (since they're likely to be very useful outside of jose).

Also, relace usages of BASE64_REGEXP with base64url.

A Better Test for JWT.isJWE

The current test assumes that there will be a header property as opposed to a protected header.

This needs to be improved for use with the JSON General and Flattened Serializations (see #5).

Certificating JWK public keys (JWC)

We've been experimenting with certificating JWK public key values. Like X.509 certificates, this key sharing scheme minimizes the need for fetching public keys used for encryption and signature verification. We're calling this JSON Web Certificates (JWC).

A JSON Web Certificate is created by adding descriptive properties to a JSON Web Key, representing the issuer (iss), subject (sub), and other key metadata, such as time of issue (iat), expiration (exp), and certificate identifier (jti). This JWK is then used as the payload of a JSON Web Token or JSON Web Document.

The following JWC is represented as a JSON Web Document signed with KS256.

{
  "payload": {
    "jti": "a49a290a8f185b3c30ab",
    "kid": "0f88678c349d41e4fd3e", 
    "iss": "https://example.org”, 
    "sub": "[email protected]",
    "kty": "EC",
    "crv": "K-256",
    "x": "wAa1grkJ4BLUJdNgRUG4ovcz3zXK6BeA3sDP3VT66As",
    "y": "fbZJQJgvxcgLupPb7Qp_7gL43FfTUHwBGNHJoProq34",
    "key_ops": [ "verify" ],
    "ext": true,
    "Iat": 1498398688,
    "exp": 1529934688
  },
  "signatures": [
    {
      "protected": {
        "alg": "KS256",
        "kid": "LGm6w06md1w",
        "jku": "https://example.org/jwks"
      },
      "signature": "MEYCIQDEwsaHMKPlH0teADyn5gs9CPY8c3O7z70N-xjwmM_JJwIhAPzzkSOuJ2..."
    }
  ]
}

A certificate can also be serialized as a compact JWT (line breaks for readability):

eyJhbGciOiJLUzI1NiIsImtpZCI6Ims1VHd4Y2UwYlJjIiwiamt1IjoiaHR0cDovL2xvY2FsaG9
zdDo1MTUwL2p3a3MifQ.eyJqdGkiOiJkMzkyNDE0NThjMjNiN2JmYjk1ZiIsImtpZCI6ImU
5N2M2MDZjMjliYWRjNWRhNDBkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MTUwIiwic
3ViIjoic21pdGhAYW52aWwuaW8iLCJrdHkiOiJFQyIsImNydiI6IkstMjU2IiwieCI6IndBYTF
ncmtKNEJMVUpkTmdSVUc0b3ZjejN6WEs2QmVBM3NEUDNWVDY2QXMiLCJ5IjoiZmJ
aSlFKZ3Z4Y2dMdXBQYjdRcF83Z0w0M0ZmVFVId0JHTkhKb1Byb3EzNCIsImtleV9vcH
MiOlsidmVyaWZ5Il0sImV4dCI6dHJ1ZSwiaWF0IjoxNDk4NDI0NTQ2LCJleHAiOjE1Mjk5
NjA1NDZ9.MEUCIQD2WRGkcZd-50q-jZtIl9tHqVmyOQ1zRLVTym2hAFyfLAIgVgZmI_5
7ouVwg5cZFHvPViIMo0u4kuDHY_YDGXGn6r0

A JWC can be included in a JOSE Protected Header object like so:

{
  "payload": {
    "hello": "world"
  },
  "signatures": [
    {
      "protected": {
        "alg": "KS256",
        "jwc": "eyJhbGciOiJLUzI1NiIsImtpZCI6Ims1VHd4Y2UwYlJjIiwiamt1IjoiaHR0cDovL2xvY2FsaG9zdDo1MTUwL2p3a3MifQ.eyJqdGkiOiJkMzkyNDE0NThjMjNiN2JmYjk1ZiIsImtpZCI6ImU5N2M2MDZjMjliYWRjNWRhNDBkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MTUwIiwic3ViIjoic21pdGhAYW52aWwuaW8iLCJrdHkiOiJFQyIsImNydiI6IkstMjU2IiwieCI6IndBYTFncmtKNEJMVUpkTmdSVUc0b3ZjejN6WEs2QmVBM3NEUDNWVDY2QXMiLCJ5IjoiZmJaSlFKZ3Z4Y2dMdXBQYjdRcF83Z0w0M0ZmVFVId0JHTkhKb1Byb3EzNCIsImtleV9vcHMiOlsidmVyaWZ5Il0sImV4dCI6dHJ1ZSwiaWF0IjoxNDk4NDI0NTQ2LCJleHAiOjE1Mjk5NjA1NDZ9.MEUCIQD2WRGkcZd-50q-jZtIl9tHqVmyOQ1zRLVTym2hAFyfLAIgVgZmI_57ouVwg5cZFHvPViIMo0u4kuDHY_YDGXGn6r0"
      },
      "signature": "MEUCIAThnzOzVUFzv7CyZnNOou9xjrkk_4CYfpwRUF0j4OWyAiEAyOZFETZojdRjvaB-sLjIX7xOPn8_1w6CMuDy8AU1Plk"
    }
  ]
}

We now need to consider drafting a specification targeting IETF and incorporating necessary functions into this package.

Update tests for JWK/JWA.importKeys()

The original test stubs for JWK.importKeys() expect the method to resolve with a JWK instance (and at the moment, it just resolves with a plain object with the relevant properties), and to have a CryptoKey property (which it doesn't seem to?).

Are those still correct expectations?

Implement JWE

With the AES-CBC and AES-GCM in the works in webcrypto we now have the ability to do JWE.

This will benefit us with regard to encrypted databases, etc.

Deterministic JSON Stringify

A recurring problem that has been seen with regards to hashes and signatures is when properties get switched around between JSON.stringify calls which results in hashes not matching and signatures not verifying successfully despite semantically identical objects.

For example, an object { alg: 'RS256', kid: 'abcd' } could be stringified as:

{"alg":"RS256","kid":"abcd"}

or

{"kid":"abcd","alg":"RS256"}

The result of the stringify operation depends on the original order of the properties in the JSON string (my understanding is that the order is preserved) and the order in which properties are added to the object.

My recommendation is that we replace our stringify calls with our own deterministic stringify function, or one that we import such as json-stable-stringify.

Implement jwt.isSigned() helper method (or similar)

It would be helpful for various app logic to have a JWT instance method, something like jwt.isSigned(), to be able to tell whether the jwt has one or multiple signatures (signed), or has alg: 'none' in the header (unsigned).

For the moment, you have to do something like if (jwt.signature || jwt.signatures) -- if (jwt.isSigned()) would be more readable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.