move bcrypt function to webworkers

This commit is contained in:
2024-11-17 15:31:19 +02:00
parent 47c2c6ce16
commit db754eb121
5 changed files with 117 additions and 24 deletions

View File

@@ -0,0 +1,12 @@
import bcrypt from 'bcryptjs'
self.onmessage = function (e) {
const { hashBase64, salt } = e.data;
try {
const result = bcrypt.hashSync(hashBase64, salt);
self.postMessage({ result });
} catch (error) {
self.postMessage({ error: error.message });
}
};

View File

@@ -0,0 +1,71 @@
import { bcrypt } from 'hash-wasm';
self.onmessage = async function (e) {
const { hashBase64, salt } = e.data;
try {
// Split the salt string
const parts = salt.split('$');
if (parts.length !== 4) {
throw new Error('Invalid salt format');
}
// Extract the raw salt from the bcrypt salt string
const rawSalt = parts[3]; // e.g., "IxVE941tXVUD4cW0TNVm.O"
// Bcrypt's custom Base64 decoding function
function bcryptBase64Decode(base64String) {
const base64Code = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const inverseBase64Code = {};
for (let i = 0; i < base64Code.length; i++) {
inverseBase64Code[base64Code[i]] = i;
}
const bytes = [];
let i = 0;
while (i < base64String.length) {
const c1 = inverseBase64Code[base64String.charAt(i++)];
const c2 = inverseBase64Code[base64String.charAt(i++)];
bytes.push(((c1 << 2) | (c2 >> 4)) & 0xff);
if (i >= base64String.length) break;
const c3 = inverseBase64Code[base64String.charAt(i++)];
bytes.push(((c2 << 4) | (c3 >> 2)) & 0xff);
if (i >= base64String.length) break;
const c4 = inverseBase64Code[base64String.charAt(i++)];
bytes.push(((c3 << 6) | c4) & 0xff);
}
return new Uint8Array(bytes);
}
// Decode the bcrypt Base64 salt into a Uint8Array
const saltArray = bcryptBase64Decode(rawSalt);
if (saltArray.length !== 16) {
throw new Error('Salt must be 16 bytes long for hash-wasm.');
}
// Extract the cost factor
const costFactor = parseInt(parts[2], 10);
// Determine if 'hashBase64' is the password or needs decoding
const password = hashBase64; // Adjust if 'hashBase64' is encoded
// Compute the hash using hash-wasm
const result = await bcrypt({
password: password,
salt: saltArray,
costFactor: costFactor,
outputType: 'encoded', // Outputs in bcrypt format
});
// Return the result to the main thread
self.postMessage({ result });
} catch (error) {
console.error('Error in Web Worker:', error);
self.postMessage({ error: error.message });
}
};

View File

@@ -1,9 +1,10 @@
// @ts-nocheck
import {bytes_to_base64 as bytesToBase64, Sha512} from 'asmcrypto.js'
import bcrypt from 'bcryptjs'
import utils from '../utils/utils'
import { crypto } from '../constants/decryptWallet'
import { crypto as crypto2 } from '../constants/decryptWallet'
import BcryptWorker from './bcryptworker.worker.js?worker';
const stringtoUTF8Array = (message)=> {
if (typeof message === 'string') {
var s = unescape(encodeURIComponent(message)) // UTF-8
@@ -15,6 +16,29 @@ const stringtoUTF8Array = (message)=> {
return message
}
const bcryptInWorker = (hashBase64, salt) => {
return new Promise((resolve, reject) => {
const worker = new BcryptWorker()
worker.onmessage = (e) => {
const { result, error } = e.data;
if (error) {
reject(error);
} else {
resolve(result);
}
worker.terminate();
};
worker.onerror = (err) => {
reject(err.message);
worker.terminate();
};
worker.postMessage({ hashBase64, salt });
});
};
const stringToUTF8Array=(message)=> {
if (typeof message !== 'string') return message; // Assuming you still want to pass through non-string inputs unchanged
const encoder = new TextEncoder(); // TextEncoder defaults to UTF-8
@@ -23,10 +47,11 @@ const stringToUTF8Array=(message)=> {
const computekdf = async (req)=> {
const { salt, key, nonce, staticSalt, staticBcryptSalt } = req
const combinedBytes = utils.appendBuffer(new Uint8Array([]), stringToUTF8Array(`${staticSalt}${key}${nonce}`))
const sha512Hash = new Sha512().process(combinedBytes).finish().result
const sha512HashBase64 = bytesToBase64(sha512Hash)
const result = bcrypt.hashSync(sha512HashBase64.substring(0, 72), staticBcryptSalt)
const result = await bcryptInWorker(sha512HashBase64.substring(0, 72), staticBcryptSalt);
return { key, nonce, result }
}
@@ -55,8 +80,8 @@ export const kdf = async (seed, salt, threads) => {
key: seed,
salt,
nonce,
staticSalt: crypto.staticSalt,
staticBcryptSalt: crypto.staticBcryptSalt
staticSalt: crypto2.staticSalt,
staticBcryptSalt: crypto2.staticBcryptSalt
}).then(data => {
let jsonData
try {
@@ -70,6 +95,6 @@ export const kdf = async (seed, salt, threads) => {
return data.result
})
}))
const result = new Sha512().process(stringtoUTF8Array(crypto.staticSalt + seedParts.reduce((a, c) => a + c))).finish().result
const result = new Sha512().process(stringtoUTF8Array(crypto2.staticSalt + seedParts.reduce((a, c) => a + c))).finish().result
return result
}