Skip to content

Instantly share code, notes, and snippets.

@dannycoates
Created July 28, 2017 21:13
Show Gist options
  • Save dannycoates/5a927d6ab3b0a543fa6bfe5e664ebfd5 to your computer and use it in GitHub Desktop.
Save dannycoates/5a927d6ab3b0a543fa6bfe5e664ebfd5 to your computer and use it in GitHub Desktop.
<!DOCTYPE html5>
<html>
<body>
<script>
const HMAC_SHA256 = { name: 'HMAC', hash: {name: 'SHA-256'}};
const UTF8 = new TextEncoder('utf-8');
function b64(arrayBuffer) {
return btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)))
}
function concatArray(arrays) {
var size = arrays.reduce((total, a) => total + a.byteLength, 0);
var index = 0;
return arrays.reduce((result, a) => {
result.set(new Uint8Array(a), index);
index += a.byteLength;
return result;
}, new Uint8Array(size));
}
function HMAC(key) {
return window.crypto.subtle.importKey(
'raw',
key,
HMAC_SHA256,
false,
['sign']
)
}
async function HMAC_hash(key, input) {
const hmac = await HMAC(key);
return window.crypto.subtle.sign('HMAC', hmac, input)
}
async function HKDF_extract(salt, ikm) {
return HMAC_hash(salt, ikm);
}
async function HDKF_expand(prk, info, l) {
const input = concatArray([info, new Uint8Array([1])]);
const h = await HMAC_hash(prk, input);
return h.slice(0, l);
}
async function HKDF(salt, ikm, info, len) {
const x = await HKDF_extract(salt, ikm);
return HKDF_expand(x, info, len);
}
async function go() {
const key = new Uint8Array([0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef]);
const salt = new Uint8Array([1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4]);
const prk = await HKDF_extract(salt, key)
const k = await HDKF_expand(prk, UTF8.encode('Content-Encoding: aes128gcm\0'), 16);
const nonce = await HDKF_expand(prk, UTF8.encode('Content-Encoding: nonce\0'), 12);
console.log(b64(k), b64(nonce));
}
go()
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment