trasherdk / jsrsasign

The 'jsrsasign' (RSA-Sign JavaScript Library) is an opensource free cryptography library supporting RSA/RSAPSS/ECDSA/DSA signing/validation, ASN.1, PKCS#1/5/8 private/public key, X.509 certificate, CRL, OCSP, CMS SignedData, TimeStamp, CAdES JSON Web Signature/Token in pure JavaScript.
https://kjur.github.com/jsrsasign
Other
0 stars 0 forks source link

Snippet: Generate a valid ES256 token that validates on JWT.io #2

Open trasherdk opened 2 years ago

trasherdk commented 2 years ago

Generate a private key: openssl ecparam -genkey -name prime256v1 -noout -out private-key.pem

Generate a public key from the private key: openssl ec -in private-key.pem -pubout -out public-key.pem

var rs = require("jsrsasign");

var tNow = rs.KJUR.jws.IntDate.get('now');
var tEnd = rs.KJUR.jws.IntDate.get('now + 1day');
var teamId = 'SEARCHADS.xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
var clientId = "foo";
var keyId = 'xxxxxx-xxxx-xxxx-xxxxxxxxxxx';
var privateKey = `-----BEGIN EC PRIVATE KEY-----
...
-----END EC PRIVATE KEY-----`;
var publicKey = `-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----`;

var oHeader = {
  "alg": "ES256",
  "kid": keyId
}

var oPayload = {
  "iss": teamId,
  "iat": tNow,
  "exp": tEnd,
  "aud": "https://appleid.apple.com",
  "sub": clientId
}

var sHeader = JSON.stringify(oHeader);
var sPayload = JSON.stringify(oPayload);

var sKey = rs.KEYUTIL.getKey(privateKey);  
var sResult = rs.KJUR.jws.JWS.sign('ES256', sHeader, sPayload, sKey);

console.log(sResult);

console.log(rs.KJUR.jws.JWS.verifyJWT(sResult, publicKey, {
  alg: ['ES256'],
  verifyAt: rs.KJUR.jws.IntDate.get('now')
}));

Source: https://github.com/kjur/jsrsasign/issues/541#issuecomment-1063946948

trasherdk commented 2 years ago

A similar version that encode, sign, verify and decode JWT token. It does NOT validate on jwt.io

#!/bin/bash

BASE=$(dirname $(realpath $0))
echo "Working in ${BASE}"
cd ${BASE}

CA="${BASE}/ca"
TEMP="${BASE}/temp"

openssl ecparam -genkey -name prime256v1 -noout -out "${CA}/private-jwt-key.pem" || exit 1

openssl ec -in "${CA}/private-jwt-key.pem" -pubout -out "${CA}/public-jwt-key.pem" || exit 1
import { readFileSync } from 'fs'
import jsrsasign from 'jsrsasign'
import path, { resolve } from 'path'
import { fileURLToPath } from 'url'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

const Private = readFileSync(resolve(__dirname, '../ca/private-jwt-key.pem')).toString('utf8')
const Public = readFileSync(resolve(__dirname, '../ca/public-jwt-key.pem')).toString('utf8')

const tNow = jsrsasign.KJUR.jws.IntDate.get('now')
const tEnd = jsrsasign.KJUR.jws.IntDate.get('now + 1day')
const teamId = 'SEARCHADS.xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
const clientId = 'foo'
const keyId = 'xxxxxx-xxxx-xxxx-xxxxxxxxxxx'

const oHeader = {
  alg: 'ES256',
  kid: keyId
}

const oPayload = {
  iss: teamId,
  iat: tNow,
  exp: tEnd,
  aud: 'https://appleid.apple.com',
  sub: clientId
}

const sHeader = JSON.stringify(oHeader)
const sPayload = JSON.stringify(oPayload)
let sResult
try {
  const sKey = jsrsasign.KEYUTIL.getKey(Private)
  sResult = jsrsasign.KJUR.jws.JWS.sign('ES256', sHeader, sPayload, sKey)
} catch (error) {
  console.log(error)
  process.exit()
}

console.log(sResult)

console.log('verifyJWT:', jsrsasign.KJUR.jws.JWS.verifyJWT(sResult, Public, {
  alg: ['ES256'],
  verifyAt: jsrsasign.KJUR.jws.IntDate.get('now')
}))

let headerObj
let payloadObj
try {
  headerObj = jsrsasign.KJUR.jws.JWS.readSafeJSONString(jsrsasign.b64utoutf8(sResult.split('.')[0]))
} catch (error) {
  console.log('headerObj:', error)
  process.exit()
}

try {
  payloadObj = jsrsasign.KJUR.jws.JWS.readSafeJSONString(jsrsasign.b64utoutf8(sResult.split('.')[1]))
} catch (error) {
  console.log('payloadObj:', error)
  process.exit()
}

console.log('Header:', headerObj)
console.log('Payload:', payloadObj)