Skip to content

Instantly share code, notes, and snippets.

@bshambaugh
Created September 23, 2022 23:35
Show Gist options
  • Save bshambaugh/427bb7e41fbe3f0169745fd3e821c2a5 to your computer and use it in GitHub Desktop.
Save bshambaugh/427bb7e41fbe3f0169745fd3e821c2a5 to your computer and use it in GitHub Desktop.
This does not produce the correct signature
/// replicating section: A.3. Example JWS Using ECDSA P-256 SHA-256 [https://www.rfc-editor.org/rfc/rfc7515#appendix-A.3]
/// seeAlso: [https://www.rfc-editor.org/rfc/rfc7518#section-3.4]
var EC = require('elliptic').ec;
var secp256r1 = new EC('p256');
var sha256 = require('@stablelib/sha256')
var u8a = require('uint8arrays')
var HMAC = require("@stablelib/hmac").HMAC
var SHA256 = require("@stablelib/sha256").SHA256
var sjcl = require('sjcl')
// const header = '{\"typ\":\"JWT\"\,\"alg\":\"ES256\"\}'
const header = '{\"alg\":\"ES256\"}'
const Eightbit = u8a.fromString(header)
const base64 = u8a.toString(Eightbit,'base64url')
console.log(header)
console.log(Eightbit)
console.log(base64)
console.log("")
// const payload = '{\"iss\":\"joe\",\"exp\":1300819380,\"http://example.com/is_root\":true}'
const payload = '{\"iss\":\"joe\",\"exp\":1300819380,\"http://example.com/is_root\":true}'
const EightbitPayload = u8a.fromString(payload)
const base64Payload = u8a.toString(EightbitPayload,'base64url')
const signingInput = base64+'.'+base64Payload
const u8aSigningInput = u8a.fromString(signingInput)
console.log(payload)
console.log(EightbitPayload)
console.log(base64Payload)
console.log("")
console.log(u8aSigningInput)
// sign with this JWK
/*
{"kty":"EC",
"crv":"P-256",
"x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
"y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
"d":"jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI"
}
*/
const base64urlx = "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU"
const base64urly = "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
const base64urld = "jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI"
const x = u8a.toString(u8a.fromString(base64urlx,'base64url'),'base16')
console.log(x)
const y = u8a.toString(u8a.fromString(base64urly,'base64url'),'base16')
console.log(y)
const privateKey = u8a.toString(u8a.fromString(base64urld,'base64url'),'base16')
console.log(privateKey)
const publicKey = x+y
console.log('PublicKey from base64url')
console.log(publicKey)
//const privateKey = '7af6732f581d005afcf216f6385ff6371029242cc60840dd7d2a7a5503b7d21'
const keyPair = secp256r1.keyFromPrivate(privateKey,'hex')
const pk = keyPair.getPublic('hex')
console.log('PublicKey from private')
console.log(pk)
/*
const myBitArray = sjcl.hash.sha256.hash(signingInput)
const hashedMsg = sjcl.codec.hex.fromBits(myBitArray)
*/
const hashedMsg = sha256.hash(u8aSigningInput)
console.log('the hashed message is')
console.log(hashedMsg)
// the hashing algorithm looks healthy...
// what about the signature? it looks fishy....
const {r, s } = keyPair.sign(hashedMsg)
//const newR = leftpad(r.toString('hex'))
//const newY = leftpad(s.toString('hex'))
const signature = keyPair.sign(hashedMsg)
/*
const signatureR = (signature.r).toString('hex')
console.log(u8a.fromString(signatureR,'base16'))
*/
//console.log(signature)
const signatureHex = leftpad((signature.r).toString('hex')) + leftpad((signature.s).toString('hex'))
//const signatureHex = newR + newY
//console.log(signatureHex)
u8aSig = u8a.fromString(signatureHex)
b64Sig = u8a.toString(u8aSig,'base64url')
//console.log(b64Sig)
//console.log(keyPair.verify(hashedMsg, signature))
console.log(signingInput+'.'+b64Sig)
// Verify signature
//console.log(keyPair.verify(hashedMsg, signature));
// from the did-jwt library:::
function leftpad(data, size = 64) {
if (data.length === size) return data
return '0'.repeat(size - data.length) + data
}
@chongkan
Copy link

  1. Copy the gist into an index.js file
  2. Copy the following code into a package.json file
  3. % npm install
  4. % npm start
{
  "name": "Example JWS Using ECDSA P-256 SHA-256",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@stablelib/hmac": "^1.0.1",
    "@stablelib/sha256": "^1.0.1",
    "base64url-universal": "^2.0.0",
    "elliptic": "^6.5.4",
    "sjcl": "^1.0.8",
    "uint8arrays": "^3.1.0"
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment