Skip to content

Instantly share code, notes, and snippets.

@OR13
Last active December 5, 2019 18:44
Show Gist options
  • Save OR13/862380ac861ee2d937df2653c22ea44a to your computer and use it in GitHub Desktop.
Save OR13/862380ac861ee2d937df2653c22ea44a to your computer and use it in GitHub Desktop.
JWS b64 Tests
node_modules
{
"name": "862380ac861ee2d937df2653c22ea44a",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"asn1.js": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.2.0.tgz",
"integrity": "sha512-Q7hnYGGNYbcmGrCPulXfkEw7oW7qjWeM4ZTALmgpuIcZLxyqqKYWxCZg2UBm8bklrnB4m2mGyJPWfoktdORD8A==",
"requires": {
"bn.js": "^4.0.0",
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0"
}
},
"base64url": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
"integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A=="
},
"base64url-universal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/base64url-universal/-/base64url-universal-1.1.0.tgz",
"integrity": "sha512-WyftvZqye29YQ10ZnuiBeEj0lk8SN8xHU9hOznkLc85wS1cLTp6RpzlMrHxMPD9nH7S55gsBqMqgGyz93rqmkA==",
"requires": {
"base64url": "^3.0.0"
}
},
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
"jose": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/jose/-/jose-1.16.1.tgz",
"integrity": "sha512-Gf1EymrO6cJvC+hhyAgMV8PXz4OQ1HitXhtZvokd4XnrF9RKmmlmSnHpMt3Og69jBKnC+7CVmbioH178Zuo2Jw==",
"requires": {
"asn1.js": "^5.2.0"
}
},
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
"integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
},
"nan": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
},
"node-gyp-build": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.0.tgz",
"integrity": "sha512-4oiumOLhCDU9Rronz8PZ5S4IvT39H5+JEv/hps9V8s7RSLhsac0TCP78ulnHXOo8X1wdpPiTayGlM1jr4IbnaQ=="
},
"sodium-native": {
"version": "2.4.6",
"resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-2.4.6.tgz",
"integrity": "sha512-Ro9lhTjot8M01nwKLXiqLSmjR7B8o+Wg4HmJUjEShw/q6XPlNMzjPkA1VJKaMH8SO8fJ/sggAKVwreTaFszS2Q==",
"requires": {
"ini": "^1.3.5",
"nan": "^2.14.0",
"node-gyp-build": "^4.1.0"
}
}
}
}
{
"name": "862380ac861ee2d937df2653c22ea44a",
"version": "1.0.0",
"description": "",
"main": "test.js",
"scripts": {
"test": "node test"
},
"repository": {
"type": "git",
"url": "git+ssh://[email protected]/862380ac861ee2d937df2653c22ea44a.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://gist.github.com/862380ac861ee2d937df2653c22ea44a"
},
"homepage": "https://gist.github.com/862380ac861ee2d937df2653c22ea44a",
"dependencies": {
"base64url-universal": "^1.1.0",
"jose": "^1.16.1",
"sodium-native": "^2.4.6"
}
}
const jose = require("jose");
const sodium = require("sodium-native");
const base64url = require("base64url-universal");
const key = {
kty: "OKP",
crv: "Ed25519",
d: "nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A",
x: "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"
};
test();
async function test() {
const goodData = new Uint8Array([127]);
try {
const sig1 = await panva(goodData);
console.log("sig1", sig1);
const sig2 = await ld(goodData);
console.log("sig2", sig2);
if (sig1 !== sig2) {
throw new Error("signatures do not match");
}
console.log("signatures match!");
} catch (e) {
console.error(e);
}
const baseData = new Uint8Array([128]);
try {
const sig1 = await panva(baseData);
console.log("sig1", sig1);
const sig2 = await ld(baseData);
console.log("sig2", sig2);
if (sig1 !== sig2) {
throw new Error("signatures do not match");
}
console.log("signatures match!");
} catch (e) {
console.error(e);
}
}
async function ld(verifyData) {
// JWS header
const header = {
alg: "EdDSA",
b64: false,
crit: ["b64"]
};
// create JWS data and sign
const encodedHeader = base64url.encode(JSON.stringify(header));
const data = createJws({ encodedHeader, verifyData });
const signature = await sign(data);
// create detached content signature
const encodedSignature = base64url.encode(signature);
return encodedHeader + ".." + encodedSignature;
}
async function panva(data) {
const header = {
alg: "EdDSA",
b64: false,
crit: ["b64"]
};
let toBeSigned = Buffer.from(data.buffer, data.byteOffset, data.length);
const flattened = jose.JWS.sign.flattened(
toBeSigned,
jose.JWK.asKey(key),
header
);
return flattened.protected + ".." + flattened.signature;
}
async function sign(data) {
const d = base64url.decode(key.d);
const x = base64url.decode(key.x);
const privateKey = Buffer.concat([d, x]);
const signature = Buffer.alloc(sodium.crypto_sign_BYTES);
await sodium.crypto_sign_detached(
signature,
Buffer.from(data.buffer, data.byteOffset, data.length),
privateKey
);
return signature;
}
function createJws({ encodedHeader, verifyData }) {
const buffer = Buffer.concat([
Buffer.from(encodedHeader + ".", "utf8"),
Buffer.from(verifyData.buffer, verifyData.byteOffset, verifyData.length)
]);
return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.length);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment