Created
March 13, 2024 02:51
-
-
Save EtherDream/217d2419d01071661acb886562b76fe6 to your computer and use it in GitHub Desktop.
WebCrypto PBKDF2
This file contains 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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>PBKDF2 Test</title> | |
<style> | |
body, input { | |
font-family: monospace; | |
} | |
#txtLog { | |
width: 100%; | |
height: 200px; | |
} | |
</style> | |
</head> | |
<body> | |
<fieldset> | |
<legend>Params</legend> | |
<div> | |
pass: <input id="txtPwd" type="text" value="Hello"> | |
</div> | |
<div> | |
salt: <input id="txtSalt" type="text" value="123456"> | |
</div> | |
<div> | |
iter: <input id="txtIter" type="number" value="1000000"> | |
</div> | |
<div> | |
algo: | |
<select id="optAglo"> | |
<option>SHA-256</option> | |
<option>SHA-384</option> | |
<option>SHA-512</option> | |
</select> | |
</div> | |
<div> | |
size: <input id="txtSize" type="number" value="32"> | |
</div> | |
</fieldset> | |
<div> | |
<button id="btnHash">Hash</button> | |
</div> | |
<div> | |
<textarea id="txtLog" readonly></textarea> | |
</div> | |
<script> | |
async function pbkdf2(pwd, salt, iter, algo, bits) { | |
const algorithm = { | |
name: 'PBKDF2', | |
hash: algo, | |
salt: salt, | |
iterations: iter, | |
} | |
const baseKey = await crypto.subtle.importKey('raw', pwd, 'PBKDF2', false, ['deriveBits']) | |
return await crypto.subtle.deriveBits(algorithm, baseKey, bits) | |
} | |
function log(s) { | |
txtLog.value += s + '\n' | |
} | |
async function onClick() { | |
const passStr = txtPwd.value | |
const saltStr = txtSalt.value | |
const passBin = new TextEncoder().encode(passStr) | |
const saltBin = new TextEncoder().encode(saltStr) | |
const iter = +txtIter.value | |
const bits = +txtSize.value * 8 | |
const algo = optAglo.options[optAglo.selectedIndex].text | |
const t0 = Date.now() | |
let result | |
try { | |
result = await pbkdf2(passBin, saltBin, iter, algo, bits) | |
} catch (err) { | |
log(err.message) | |
return | |
} | |
const t1 = Date.now() | |
const hex = Array | |
.from(new Uint8Array(result)) | |
.map(v => v.toString(16).padStart(2, '0')) | |
.join('') | |
const time = (t1 - t0) + 'ms' | |
log(`pbkdf2('${passStr}', '${saltStr}', ${iter}, '${algo}', ${bits}) = ${hex} (${time})`) | |
} | |
function main() { | |
if (!window.crypto || !crypto.subtle) { | |
const ua = navigator.userAgent | |
const ctx = isSecureContext | |
log(`Crypto API is not supported.`) | |
log(`UserAgent: ${ua}`) | |
log(`isSecureContext: ${ctx}`) | |
return | |
} | |
btnHash.onclick = onClick | |
} | |
main() | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment