Last active
August 23, 2023 02:33
-
-
Save ronnievsmith/2d5ee18f32695479b34eac75d67aae88 to your computer and use it in GitHub Desktop.
JSON Web Signature (JWS) Token via HMAC using SHA-256 w Node.js Crypto Module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Buffer } from 'node:buffer'; | |
import fs from "node:fs"; | |
import url from 'node:url'; | |
import path from "node:path"; | |
const {createHmac, generateKey} = await import('node:crypto'); | |
var claims = {name:"Joe",roles:["member","admin"]}; | |
var secretKey; | |
(async function () { | |
secretKey = await generateSecretKey(); | |
let jws = await returnJWS(claims); | |
console.log("\x1b[37mYour JWS token is: " + consoleString(jws)); | |
console.log("Paste JSON Web Token In Terminal Then Press Enter.") | |
})(); | |
function returnJWS(claims){ | |
let headerObject = { | |
alg: 'HS256', | |
typ: 'JWT', | |
kid: 'public' | |
}; | |
let headerString = JSON.stringify(headerObject); | |
let encodedHeader = Buffer.from(headerString).toString('base64url'); | |
let payloadString = JSON.stringify(claims); | |
let encodedPayload = Buffer.from(payloadString).toString('base64url'); | |
const hmac = createHmac('sha256', secretKey); | |
hmac.update(encodedHeader + '.' + encodedPayload); | |
let signature = hmac.digest('base64url'); | |
let jsonWebToken = encodedHeader + '.' + encodedPayload + '.' + signature; | |
return jsonWebToken; | |
} | |
function validateJWS(jwt){ | |
try { | |
let jwtParts = jwt.split('.'); | |
let jwtHeader = jwtParts[0]; | |
let jwtPayload = jwtParts[1]; | |
let jwtSignature = jwtParts[2].trim(); | |
let signature; | |
let header = JSON.parse(Buffer.from(jwtHeader, 'base64url').toString('utf-8')); | |
let alg = header.alg; | |
if(alg === "HS256"){ | |
const hmac = createHmac('sha256', secretKey); | |
hmac.update(jwtHeader + '.' + jwtPayload); | |
signature = hmac.digest('base64url').trim(); | |
console.log(signature) | |
console.log(jwtSignature) | |
if(signature == jwtSignature) { | |
return Buffer.from(jwtPayload, 'base64url').toString('utf-8') | |
} else { | |
return "\x1b[31mInvalid Token!\x1b[37m"; | |
} | |
} else { | |
throw (error) | |
} | |
} catch (e) { | |
console.log (e); | |
return "\x1b[31mInvalid Token!\x1b[37m"; | |
} | |
} | |
function generateSecretKey () { | |
return new Promise(function(resolve, reject) { | |
generateKey('aes', { length: 256 }, (err, key) => { | |
if (err) { | |
reject (err); | |
} | |
resolve (key) | |
}); | |
}); | |
} | |
export default {returnJWS, validateJWS}; | |
process.stdin.setEncoding('utf8'); | |
process.stdin.on('readable', async () => { | |
let chunk; | |
while ((chunk = process.stdin.read()) !== null) { | |
console.log(await validateJWS(chunk)); | |
} | |
}); | |
function consoleString(token){ | |
let tokenParts = token.split(/(\.)/); | |
let colors = ["32m","31m","33m","34m","36m"]; | |
let color = "\x1b[X"; | |
let str = "" | |
tokenParts.forEach(function(part,index){ | |
if(part != "."){ | |
str += color.replace("X",colors.shift()) | |
} | |
str += part; | |
str += "\x1b[37m" | |
}) | |
return str; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment