Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Argon2 hash operations #661

Merged
merged 2 commits into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"@astronautlabs/amf": "^0.0.6",
"@babel/polyfill": "^7.12.1",
"@blu3r4y/lzma": "^2.3.3",
"argon2-browser": "^1.11.1",
"arrive": "^2.4.1",
"avsc": "^5.7.4",
"bcryptjs": "^2.4.3",
Expand Down
2 changes: 2 additions & 0 deletions src/core/config/Categories.json
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@
"Bcrypt compare",
"Bcrypt parse",
"Scrypt",
"Argon2",
"Argon2 compare",
"NT Hash",
"LM Hash",
"Fletcher-8 Checksum",
Expand Down
101 changes: 101 additions & 0 deletions src/core/operations/Argon2.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* @author Tan Zhen Yong [tzy@beyondthesprawl.com]
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/

import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import argon2 from "argon2-browser";

/**
* Argon2 operation
*/
class Argon2 extends Operation {

/**
* Argon2 constructor
*/
constructor() {
super();

this.name = "Argon2";
this.module = "Crypto";
this.description = "Argon2 is a key derivation function that was selected as the winner of the Password Hashing Competition in July 2015. It was designed by Alex Biryukov, Daniel Dinu, and Dmitry Khovratovich from the University of Luxembourg.<br><br>Enter the password in the input to generate its hash.";
this.infoURL = "https://wikipedia.org/wiki/Argon2";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
"name": "Salt",
"type": "string",
"value": "somesalt"
},
{
"name": "Iterations",
"type": "number",
"value": 3
},
{
"name": "Memory (KiB)",
"type": "number",
"value": 4096
},
{
"name": "Parallelism",
"type": "number",
"value": 1
},
{
"name": "Hash length (bytes)",
"type": "number",
"value": 32
},
{
"name": "Type",
"type": "option",
"value": ["Argon2i", "Argon2d", "Argon2id"],
"defaultIndex": 0
}
];
}

/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
async run(input, args) {
const argon2Types = {
"Argon2i": argon2.ArgonType.Argon2i,
"Argon2d": argon2.ArgonType.Argon2d,
"Argon2id": argon2.ArgonType.Argon2id
};

const salt = args[0],
time = args[1],
mem = args[2],
parallelism = args[3],
hashLen = args[4],
type = argon2Types[args[5]];

try {
const result = await argon2.hash({
pass: input,
salt,
time,
mem,
parallelism,
hashLen,
type,
});

return result.encoded;
} catch (err) {
throw new OperationError(`Error: ${err.message}`);
}
}

}

export default Argon2;
58 changes: 58 additions & 0 deletions src/core/operations/Argon2Compare.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* @author Tan Zhen Yong [tzy@beyondthesprawl.com]
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/

import Operation from "../Operation.mjs";
import argon2 from "argon2-browser";

/**
* Argon2 compare operation
*/
class Argon2Compare extends Operation {

/**
* Argon2Compare constructor
*/
constructor() {
super();

this.name = "Argon2 compare";
this.module = "Crypto";
this.description = "Tests whether the input matches the given Argon2 hash. To test multiple possible passwords, use the 'Fork' operation.";
this.infoURL = "https://wikipedia.org/wiki/Argon2";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
"name": "Hash",
"type": "string",
"value": ""
}
];
}

/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
async run(input, args) {
const encoded = args[0];

try {
await argon2.verify({
pass: input,
encoded
});

return `Match: ${input}`;
} catch (err) {
return "No match";
}
}

}

export default Argon2Compare;
12 changes: 12 additions & 0 deletions tests/node/tests/operations.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ Tiger-128`;

}),

it("argon2", async () => {
const result = await chef.argon2("argon2password");
assert.strictEqual(result.toString(), "$argon2i$v=19$m=4096,t=3,p=1$c29tZXNhbHQ$s43my9eBljQADuF/LWCG8vGqwAJzOorKQ0Yog8jFvbw");
}),

it("argon2 compare", async () => {
const result = await chef.argon2Compare("argon2password", {
hash: "$argon2i$v=19$m=4096,t=3,p=1$c29tZXNhbHQ$s43my9eBljQADuF/LWCG8vGqwAJzOorKQ0Yog8jFvbw"
});
assert.strictEqual(result.toString(), "Match: argon2password");
}),

it("Bcrypt", async () => {
const result = await chef.bcrypt("Put a Sock In It");
const strResult = result.toString();
Expand Down
12 changes: 7 additions & 5 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ module.exports = {
}
},
module: {
// argon2-browser loads argon2.wasm by itself, so Webpack should not load it
noParse: /node_modules\/argon2-browser\/dist\/argon2\.wasm$/,
rules: [
{
test: /\.m?js$/,
Expand All @@ -127,11 +129,11 @@ module.exports = {
loader: "babel-loader"
},
{
test: /node-forge/,
loader: "imports-loader",
options: {
additionalCode: "var jQuery = false;"
}
test: /node_modules\/argon2-browser\/dist\/argon2\.wasm$/,
// Load argon2.wasm as base64-encoded binary file
// expected by argon2-browser
loaders: "base64-loader",
type: "javascript/auto"
},
{
test: /prime.worker.min.js$/,
Expand Down