feat: using crypto.scrypt instead of bcrypt

This commit is contained in:
chenos 2022-02-10 19:53:18 +08:00
parent 47fa83032c
commit 7e76c54012
5 changed files with 43 additions and 100 deletions

View File

@ -14,15 +14,11 @@
"dependencies": {
"@nocobase/utils": "^0.6.0-alpha.0",
"async-mutex": "^0.3.2",
"bcrypt": "^5.0.0",
"deepmerge": "^4.2.2",
"flat": "^5.0.2",
"glob": "^7.1.6",
"sequelize": "^6.9.0"
},
"devDependencies": {
"@types/bcrypt": "^5.0.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/nocobase/nocobase.git",

View File

@ -1,9 +1,17 @@
import crypto from 'crypto';
import { DataTypes } from 'sequelize';
import { BaseColumnFieldOptions, Field } from './field';
import bcrypt from 'bcrypt';
export interface PasswordFieldOptions extends BaseColumnFieldOptions {
type: 'password';
/**
* @default 64
*/
length?: number;
/**
* @default 8
*/
randomBytesSize?: number;
}
export class PasswordField extends Field {
@ -11,8 +19,27 @@ export class PasswordField extends Field {
return DataTypes.STRING;
}
async verify(data: string | Buffer, encrypted: string) {
return await bcrypt.compare(data, encrypted);
async verify(password: string, hash: string) {
const { length = 64, randomBytesSize = 8 } = this.options;
return new Promise((resolve, reject) => {
const salt = hash.substring(0, randomBytesSize * 2);
const key = hash.substring(randomBytesSize * 2);
crypto.scrypt(password, salt, length / 2 - randomBytesSize, (err, derivedKey) => {
if (err) reject(err);
resolve(key == derivedKey.toString('hex'));
});
});
}
async hash(password: string) {
const { length = 64, randomBytesSize = 8 } = this.options;
return new Promise((resolve, reject) => {
const salt = crypto.randomBytes(randomBytesSize).toString('hex');
crypto.scrypt(password, salt, length / 2 - randomBytesSize, (err, derivedKey) => {
if (err) reject(err);
resolve(salt + derivedKey.toString('hex'));
});
});
}
init() {
@ -23,10 +50,7 @@ export class PasswordField extends Field {
}
const value = model.get(name) as string;
if (value) {
if (value.startsWith('$2b$10$') && value.length === 60) {
return;
}
const hash = await bcrypt.hash(value, 10);
const hash = await this.hash(value);
model.set(name, hash);
} else {
model.set(name, null);

View File

@ -8,9 +8,7 @@
"build:cjs": "tsc --project tsconfig.build.json",
"build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
},
"dependencies": {
"crypto-random-string": "^3.3.0"
},
"dependencies": {},
"devDependencies": {
"@nocobase/test": "^0.6.0-alpha.0"
},

View File

@ -1,6 +1,6 @@
import { Context, Next } from '@nocobase/actions';
import { PasswordField } from '@nocobase/database';
import cryptoRandomString from 'crypto-random-string';
import crypto from 'crypto';
export async function check(ctx: Context, next: Next) {
if (ctx.state.currentUser) {
@ -33,7 +33,7 @@ export async function signin(ctx: Context, next: Next) {
ctx.throw(401, '密码错误,请您重新输入');
}
if (!user.token) {
user.token = cryptoRandomString({ length: 20 });
user.token = crypto.randomBytes(20).toString('hex');
await user.save();
}
ctx.body = user.toJSON();
@ -78,7 +78,7 @@ export async function lostpassword(ctx: Context, next: Next) {
if (!user) {
ctx.throw(401, '邮箱账号未注册');
}
user.resetToken = cryptoRandomString({ length: 20 });
user.resetToken = crypto.randomBytes(20).toString('hex');
await user.save();
ctx.body = user;
await next();

View File

@ -2675,21 +2675,6 @@
stringify-entities "^3.0.1"
stringify-object "^3.3.0"
"@mapbox/node-pre-gyp@^1.0.0":
version "1.0.7"
resolved "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.7.tgz#a26919cac6595662703330d1820a0ca206f45521"
integrity sha512-PplSvl4pJ5N3BkVjAdDzpPhVUPdC73JgttkR+LnBx2OORC1GCQsBjUeEuipf9uOaAM1SbxcdZFfR3KDTKm2S0A==
dependencies:
detect-libc "^1.0.3"
https-proxy-agent "^5.0.0"
make-dir "^3.1.0"
node-fetch "^2.6.5"
nopt "^5.0.0"
npmlog "^6.0.0"
rimraf "^3.0.2"
semver "^7.3.5"
tar "^6.1.11"
"@mrmlnc/readdir-enhanced@^2.2.1":
version "2.2.1"
resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
@ -3001,13 +2986,6 @@
dependencies:
"@babel/types" "^7.3.0"
"@types/bcrypt@^5.0.0":
version "5.0.0"
resolved "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz#a835afa2882d165aff5690893db314eaa98b9f20"
integrity sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==
dependencies:
"@types/node" "*"
"@types/body-parser@*":
version "1.19.2"
resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0"
@ -4114,7 +4092,7 @@ aproba@^1.0.3:
resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
"aproba@^1.0.3 || ^2.0.0", aproba@^2.0.0:
aproba@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc"
integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==
@ -4124,14 +4102,6 @@ arch@^2.1.1:
resolved "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11"
integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==
are-we-there-yet@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c"
integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==
dependencies:
delegates "^1.0.0"
readable-stream "^3.6.0"
are-we-there-yet@~1.1.2:
version "1.1.7"
resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146"
@ -4562,14 +4532,6 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
bcrypt@^5.0.0:
version "5.0.1"
resolved "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz#f1a2c20f208e2ccdceea4433df0c8b2c54ecdf71"
integrity sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==
dependencies:
"@mapbox/node-pre-gyp" "^1.0.0"
node-addon-api "^3.1.0"
before-after-hook@^2.2.0:
version "2.2.2"
resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e"
@ -5289,11 +5251,6 @@ color-name@~1.1.4:
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-support@^1.1.2:
version "1.1.3"
resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
colorette@^2.0.16:
version "2.0.16"
resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da"
@ -5429,7 +5386,7 @@ console-browserify@^1.1.0:
resolved "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==
console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0:
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
@ -5778,13 +5735,6 @@ crypto-random-string@^1.0.0:
resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=
crypto-random-string@^3.3.0:
version "3.3.1"
resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-3.3.1.tgz#13cee94cac8001e4842501608ef779e0ed08f82d"
integrity sha512-5j88ECEn6h17UePrLi6pn1JcLtAiANa3KExyr9y9Z5vo2mv56Gh3I4Aja/B9P9uyMwyxNHAHWv+nE72f30T5Dg==
dependencies:
type-fest "^0.8.1"
css-blank-pseudo@^0.1.4:
version "0.1.4"
resolved "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5"
@ -6137,7 +6087,7 @@ detect-indent@^6.0.0:
resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6"
integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==
detect-libc@^1.0.2, detect-libc@^1.0.3:
detect-libc@^1.0.2:
version "1.0.3"
resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
@ -7394,21 +7344,6 @@ functional-red-black-tree@^1.0.1:
resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
gauge@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/gauge/-/gauge-4.0.0.tgz#afba07aa0374a93c6219603b1fb83eaa2264d8f8"
integrity sha512-F8sU45yQpjQjxKkm1UOAhf0U/O0aFt//Fl7hsrNVto+patMHjs7dPI9mFOGUKbhrgKm0S3EjW3scMFuQmWSROw==
dependencies:
ansi-regex "^5.0.1"
aproba "^1.0.3 || ^2.0.0"
color-support "^1.1.2"
console-control-strings "^1.0.0"
has-unicode "^2.0.1"
signal-exit "^3.0.0"
string-width "^4.2.3"
strip-ansi "^6.0.1"
wide-align "^1.1.2"
gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
@ -10231,7 +10166,7 @@ make-dir@^2.0.0, make-dir@^2.1.0:
pify "^4.0.1"
semver "^5.6.0"
make-dir@^3.0.0, make-dir@^3.1.0:
make-dir@^3.0.0:
version "3.1.0"
resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
@ -11097,7 +11032,7 @@ no-case@^3.0.4:
lower-case "^2.0.2"
tslib "^2.0.3"
node-addon-api@^3.0.0, node-addon-api@^3.1.0:
node-addon-api@^3.0.0:
version "3.2.1"
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161"
integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==
@ -11109,7 +11044,7 @@ node-dir@^0.1.17:
dependencies:
minimatch "^3.0.2"
node-fetch@^2.6.1, node-fetch@^2.6.5:
node-fetch@^2.6.1:
version "2.6.6"
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89"
integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==
@ -11459,16 +11394,6 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1:
gauge "~2.7.3"
set-blocking "~2.0.0"
npmlog@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/npmlog/-/npmlog-6.0.0.tgz#ba9ef39413c3d936ea91553db7be49c34ad0520c"
integrity sha512-03ppFRGlsyUaQFbGC2C8QWJN/C/K7PsfyD9aQdhVKAQIH4sQBc8WASqFBP7O+Ut4d2oo5LoeoboB3cGdBZSp6Q==
dependencies:
are-we-there-yet "^2.0.0"
console-control-strings "^1.1.0"
gauge "^4.0.0"
set-blocking "^2.0.0"
num2fraction@^1.2.2:
version "1.2.2"
resolved "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
@ -15233,7 +15158,7 @@ tar@^4, tar@^4.4.12:
safe-buffer "^5.2.1"
yallist "^3.1.1"
tar@^6.0.2, tar@^6.1.0, tar@^6.1.11:
tar@^6.0.2, tar@^6.1.0:
version "6.1.11"
resolved "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621"
integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==
@ -16389,7 +16314,7 @@ wicked-good-xpath@^1.3.0:
resolved "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz#81b0e95e8650e49c94b22298fff8686b5553cf6c"
integrity sha1-gbDpXoZQ5JyUsiKY//hoa1VTz2w=
wide-align@^1.1.0, wide-align@^1.1.2:
wide-align@^1.1.0:
version "1.1.5"
resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3"
integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==