Vue
by tranxuanthang
HTML
<div id="app">
<h1>
Tạo password hash với PBKDF2
</h1>
<p>
Nhập mật khẩu:<br>
<input type="password" v-model="inputPassword" /><br>
Nhập salt (dạng hex):<br>
<input type="text" v-model="inputSalt" /><button @click="renewSalt">
Làm mới
</button><br>
Số iteration:<br>
<input type="number" v-model="inputIterations" /><br>
<button @click="submitPassword">
Tạo hash
</button><br>
<div v-if="loading">
Đang tính...
</div>
Mã hash của mật khẩu (dạng hex): {{ resultDigest }}<br>
</p>
</div>
Vue
// https://bitcoin.stackexchange.com/questions/52727/byte-array-to-hexadecimal-and-back-again-in-javascript
const toHexString = byteArray => {
var bufferView = new Uint8Array(byteArray);
return Array.prototype.map.call(bufferView, function (byte) {
return ("0" + (byte & 0xFF).toString(16)).slice(-2);
}).join("");
};
const toByteArray = hexString => {
var result = [];
while (hexString.length >= 2) {
result.push(parseInt(hexString.substring(0, 2), 16));
hexString = hexString.substring(2, hexString.length);
}
return new Uint8Array(result);
};
const getRandomArrayBuffer = bytesNumber => {
let byte = new Uint8Array(bytesNumber);
crypto.getRandomValues(byte);
return byte;
};
const getKeyMaterial = async (passwordString) => {
const passwordBuffer = new TextEncoder().encode(passwordString);
return await crypto.subtle.importKey("raw", passwordBuffer, "PBKDF2", false, ["deriveBits"]);
};
const getDerivedBits = async (saltBuffer, keyMaterial, iterations, bitLength) => {
const params = {
name: "PBKDF2",
salt: saltBuffer,
iterations: iterations,
hash: "SHA-256"
};
return await window.crypto.subtle.deriveBits(
params,
keyMaterial,
bitLength
);
};
new Vue({
el: "#app",
data: {
inputPassword: null,
inputSalt: null,
inputIterations: 100000,
resultDigest: null,
loading: false
},
methods: {
submitPassword: async function () {
// Cập nhật UI
this.loading = true;
this.resultSalt = null;
this.resultDigest = null;
// Tạo hash
let saltBuffer = toByteArray(this.inputSalt);
// Tạo CryptoKey object từ password đầu vào
let keyMaterial = await getKeyMaterial(this.inputPassword);
// 160: số bit của mã hash pbkdf2
let resultBuffer = await getDerivedBits(saltBuffer, keyMaterial, this.inputIterations, 160);
// Cập nhật kết quả
this.resultDigest = toHexString(new Uint8Array(resultBuffer));
// Cập nhật...