JWS + JWE integration

node v8.16.1
version: 1.0.0
Create a token the is encrypted and signed. the encrypted contents must be sighed in some locals to be considered valid. Adds a bit more to the data relyability and consitancy. Forgery is a bit harder to accomplish.
Set up dependencies and aliases:
const {JWE} = require("node-jose"); const {JWK} = require("node-jose"); const {JWS} = require("node-jose"); const {util} = require("node-jose");
Set up local variables:
contentAlg is the encryption algorithm for the token content
var contentAlg = "A128CBC-HS256"; //RSA-OAEP-256 --- Encryption method: A128CBC-HS256. AES 128-bit in CBC mode using HMAC-SHA-256-128 hash (HS256 truncated to 128 bits) var store = JWK.createKeyStore();
Generate a local private key.
await store.generate("RSA",2048,{alg:"RS256", key_ops:["sign", "decrypt", "unwrap"]}); lkey = (await store.get()); JSON.stringify(lkey.toJSON(true));
Get the Public key from the private to share with the server.
Assign key properties useful in the encryption/decryption process:
var key = lkey.toJSON(); key.use = "verify"; key.key_ops=["encrypt","verify", "wrap"];
Make the JSON public key in to a JWK and Store in the KeyStore:
var pubKey = await JWK.asKey(key); await store.add(pubKey); JSON.stringify(pubKey.toJSON());
Release local variables after their usage scope has passed.
//key = null; //pubkey = null;
Set Token Playload:
var dt = new Date(); var exp = new Date(dt.getTime() + (20 * 60 * 1000)); var payload = { "nameid":"240820080175", "activityid":"a8f769d0-a129-4ad0-8fe9-5bc7761d0331", "authmethod":"ATN", "decision":"5556", "month":"11", "day":"19", "year":"1982", "role":"User", "nbf":Math.floor((dt.getTime() / 1000)), "exp":Math.floor(exp.getTime() / 1000), "iat":Math.floor((dt.getTime() / 1000)), "iss":"http://localhost:50191", "aud":"http://localhost:50191" };
Sign the payload; generate the first token:
var token = await JWS.createSign({format: 'compact'}, lkey).update(JSON.stringify(payload), "utf8").final();
Get the server/recipient public Key:
skey = await JWK.asKey( {"kid":"qQ1hDBdtvgbtXziPRmT09XS-6oc3vugIvkHdd8Kh1rk","kty":"RSA","key_ops":["encrypt","verify","wrapKey"],"n":"vuxR5sMnOz8LUCx-8zO6MexL8s_VA1t8FIh4_eUFgebQkyCvxHvQjTtHsqExWg_rJH_qyo3_EXK5lZXbRDbXN8TTwsDs79SrDqf3NoLLSMjGe3fS97HObP1WEcy0mFUDDlvz8Cdq0jXLnrvLKx5G_Pfz52NoGa3R5Gp8KrljeOqkd0DuV5qPtPc-EBkRhjnjH_IVsBeZ3gYGW8m6GqnREtK0lHvBTcdTUgQZZUHHzbpTv6Ta1ZQbImzDCuWBzlHQqbf8Zr6hb75rYTvfpS0NHD7WOjJBQn0PPxS0FSbZOd7ns3ZwbxAfzOwi7IoIGOl62GFxmowwnRAuJNpfkHkDxQ","e":"AQAB","alg":"RSA-OAEP","use":"enc"});
Set the encryption options:
var options = { zip: false, compact: true, contentAlg: contentAlg, protect: Object.keys( { "alg": skey.alg, "kid": skey.kid, "enc": contentAlg }), fields: { "alg": skey.alg, "kid": skey.kid, "enc": contentAlg } };
Create the encrypted token (JWE) from the signed token: (JWS + JWE)
token = await JWE.createEncrypt(options, skey).update(token, "utf8").final();
token_decrypt = await JWE.createDecrypt(options, key).update(token, "utf8").final();

no comments

    sign in to comment