Simplified utility/abstraction for creating/verifying JOSE/JWT

Issue #181 new
Former user created an issue

Nimbus-JOSE-JWT framework is a great framework for applying JOSE/JWT on JSON.

1) It would be great to have a utility class that would simplify the below - Creating JWE encoded payloads - Creating JWS encoded payloads - Decrypting JWE encode payloads - Verifying signature/JWS and returning verified payload. - Generating JWT encoded payload

The common theme in all the above actions performed is to encode(JSON data) and decode(encoded data) .

The thought was, want if we abstract all the above into simple encode/decode operations. - Encode Will take in encoding type( JWS/JWE/JWT) and input data( captured all data into one model say JOSEParams) . And internally encode will invoke appropriate Signer/Encryptor .

  • Decode Will take in encoded payload and params. And internally decode will identify type of encoded data and will invoke appropriate Verifier/Decryptor

2) The second through was around creating a annotation @JOSEProperty , that can be used to annotate any field( type String) on a POJO and allowing for passing the object either through encode/decode . The encode/decode operations will identify the fields annotated with @JOSEProperty and process the fields.

Comments (8)

  1. Connect2id OSS

    Hi,

    Last year we created a framework for validating / decrypting generic JOSE messages as well as their subset, JWTs. It follows the security recommendations of the respective RFCs. You can find it in the com.nimbusds.jose.proc and com.nimbusds.jwt.proc packages.

    Here is an example usage of this framework for OAuth tokens:

    http://www.connect2id.com/products/nimbus-jose-jwt/examples/validating-jwt-access-tokens

    If you could provide some pseudo code or prototype illustrating your ideas, that would be great.

    The proposed @JOSEProperty annotation sounds useful.

  2. Karthik Kalahasthi

    Pseudo code 1) Example 1 - Encoding JSON payload

    JoseParams joseParams = new JoseParams.Builder()
        .setEncryptionAlgorithmName(ENCRYPTION_ALGO_RSA_OAEP);
        .setEncryptionMethod(ENCRYPTION_METHOD_A128CBC_HS256);
        .setEncryptionKeyIdentifier(keyID);
        .setEncryptionKey(encryptPublicKey)
        .setPayload(requestPayload)
        .build();
    
    JOSEUtility.getInstance().encode(JOSEUtility.ENCODING_TYPE_JWE, joseParams);
    //Result:Returns encode JWE string
    

    1) Example 2 - Encode and Decoding POJO fields annotated with @JOSEProperty

    //Encrypt userName field with JWE
    JoseParams joseParams = new JoseParams.Builder()
        .setEncryptionAlgorithmName(ENCRYPTION_ALGO_RSA_OAEP);
        .setEncryptionMethod(ENCRYPTION_METHOD_A128CBC_HS256);
        .setEncryptionKeyIdentifier(keyID);
        .setEncryptionKey(encryptPublicKey)
        .build();
    
    class Profile{
        @JOSEProperty
        private String userName;
        public String getUserName() {
            return userName;
        }
        public void setUserName(String userName) {
            this.userName = userName;
        }
    }   
    
    Profile profile =  new Profile();
    profile.setUserName("MyUserName");
    JOSEUtility.getInstance().encode(JOSEUtility.ENCODING_TYPE_JWE, profile,Profile.class, joseParams);
    //Result: profile object will now have the 'userName' field encoded as JWE
    
    //Decode 
    joseParams = new JoseParams.Builder()
        .setEncryptionKey(encryptPrivateKey)
        .build();
    JOSEUtility.getInstance().decode(profile,Profile.class, joseParams);
    

    Thank You.

  3. Connect2id OSS

    Thanks a lot for that! We are now looking closer into your suggestion.

    Regarding fields / methods annotated with @JOSEProperty : is the username encrypted transparently (i.e. it is internally encrypted, but the getter will always return the plain text value), or is the getter returning the ciprhertext?

  4. Karthik Kalahasthi

    Thanks for considering.

    On the @JOSEProperty , once the POJO containing the annotated fields passes through the JOSEUtility.getInstance().encode(...) , the getter will return the ciprhertext.
    Similarly if the field holds cipehertext and is passed through JOSEUtility.getInstance().decode(..) , the getter will return the plain/decode text.

    Example

    Profile profile =  new Profile();
    profile.setUserName("MyUserName");
    JOSEUtility.getInstance().encode(JOSEUtility.ENCODING_TYPE_JWE, profile,Profile.class, joseParams);
    
    log.info( profile.getUserName() ) ; // -->  will print JWE encoded string.
    
    //Decode 
    joseParams = new JoseParams.Builder()
        .setEncryptionKey(encryptPrivateKey)
        .build();
    JOSEUtility.getInstance().decode(profile,Profile.class, joseParams);
    
    log.info( profile.getUserName() ) ; // -->  will print "MyUserName"  string.
    
  5. Karthik Kalahasthi

    Can you please provide an updated on this thread. Based on your feedback we would like to submit a pull request with the JOSEUtility code. -Thanks,

  6. Vladimir Dzhuvinov

    What is your use case for having object members that are made encrypted this way?

    I'm reluctant to have a feature in the library that is not immediately obvious how it can be useful, or will not be widely used.

    In terms of annotations, I was considering a @JWTClaim annotation, to enable a Java object to be turned into a JWT claims set. Then maybe together with the mentioned Profile, to perform the actual crypto op (signing, encryption, signing + encryption).

  7. Karthik Kalahasthi

    My use case was mostly for JOSE. And fields annotated with @JOSEProperty were encoded/decoded with JWE/JWS. And for supporting claims I was planning to use the JoseParams( mentioned above in my example).

    But like you mentioned, I like the the idea of @JWTClaim way to identify a claim.

    Do you already have a feature branch cut out for the enhancement's ?

  8. Log in to comment