Merge pull request #501 from kassi/fernet

Add Fernet encryption/decryption operation
This commit is contained in:
a3957273 2024-02-22 01:15:24 +00:00 committed by GitHub
commit c4e7c41a6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 216 additions and 1 deletions

15
package-lock.json generated
View File

@ -40,6 +40,7 @@
"escodegen": "^2.1.0", "escodegen": "^2.1.0",
"esprima": "^4.0.1", "esprima": "^4.0.1",
"exif-parser": "^0.1.12", "exif-parser": "^0.1.12",
"fernet": "^0.3.2",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"flat": "^6.0.1", "flat": "^6.0.1",
"geodesy": "1.1.3", "geodesy": "1.1.3",
@ -7100,6 +7101,15 @@
"pend": "~1.2.0" "pend": "~1.2.0"
} }
}, },
"node_modules/fernet": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/fernet/-/fernet-0.3.2.tgz",
"integrity": "sha512-VPwO4hF9sp8YrCeiOjMb4HTg5WV5VC7Nk2EG3pfotqW9ZHa3aNnR+oGiOZu8k0Jp4VxJi0RTJwHmloyjWs+Mzg==",
"dependencies": {
"crypto-js": "~4.2.0",
"urlsafe-base64": "1.0.0"
}
},
"node_modules/file-entry-cache": { "node_modules/file-entry-cache": {
"version": "6.0.1", "version": "6.0.1",
"dev": true, "dev": true,
@ -14081,6 +14091,11 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/urlsafe-base64": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz",
"integrity": "sha512-RtuPeMy7c1UrHwproMZN9gN6kiZ0SvJwRaEzwZY0j9MypEkFqyBaKv176jvlPtg58Zh36bOkS0NFABXMHvvGCA=="
},
"node_modules/utf8": { "node_modules/utf8": {
"version": "3.0.0", "version": "3.0.0",
"license": "MIT" "license": "MIT"

View File

@ -122,6 +122,7 @@
"escodegen": "^2.1.0", "escodegen": "^2.1.0",
"esprima": "^4.0.1", "esprima": "^4.0.1",
"exif-parser": "^0.1.12", "exif-parser": "^0.1.12",
"fernet": "^0.3.2",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"flat": "^6.0.1", "flat": "^6.0.1",
"geodesy": "1.1.3", "geodesy": "1.1.3",

View File

@ -86,6 +86,8 @@
"DES Decrypt", "DES Decrypt",
"Triple DES Encrypt", "Triple DES Encrypt",
"Triple DES Decrypt", "Triple DES Decrypt",
"Fernet Encrypt",
"Fernet Decrypt",
"LS47 Encrypt", "LS47 Encrypt",
"LS47 Decrypt", "LS47 Decrypt",
"RC2 Encrypt", "RC2 Encrypt",

View File

@ -0,0 +1,63 @@
/**
* @author Karsten Silkenbäumer [github.com/kassi]
* @copyright Karsten Silkenbäumer 2019
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import fernet from "fernet";
/**
* FernetDecrypt operation
*/
class FernetDecrypt extends Operation {
/**
* FernetDecrypt constructor
*/
constructor() {
super();
this.name = "Fernet Decrypt";
this.module = "Default";
this.description = "Fernet is a symmetric encryption method which makes sure that the message encrypted cannot be manipulated/read without the key. It uses URL safe encoding for the keys. Fernet uses 128-bit AES in CBC mode and PKCS7 padding, with HMAC using SHA256 for authentication. The IV is created from os.random().<br><br><b>Key:</b> The key must be 32 bytes (256 bits) encoded with Base64.";
this.infoURL = "https://asecuritysite.com/encryption/fer";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
"name": "Key",
"type": "string",
"value": ""
},
];
this.patterns = [
{
match: "^[A-Z\\d\\-_=]{20,}$",
flags: "i",
args: []
},
];
}
/**
* @param {String} input
* @param {Object[]} args
* @returns {String}
*/
run(input, args) {
const [secretInput] = args;
try {
const secret = new fernet.Secret(secretInput);
const token = new fernet.Token({
secret: secret,
token: input,
ttl: 0
});
return token.decode();
} catch (err) {
throw new OperationError(err);
}
}
}
export default FernetDecrypt;

View File

@ -0,0 +1,54 @@
/**
* @author Karsten Silkenbäumer [github.com/kassi]
* @copyright Karsten Silkenbäumer 2019
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import fernet from "fernet";
/**
* FernetEncrypt operation
*/
class FernetEncrypt extends Operation {
/**
* FernetEncrypt constructor
*/
constructor() {
super();
this.name = "Fernet Encrypt";
this.module = "Default";
this.description = "Fernet is a symmetric encryption method which makes sure that the message encrypted cannot be manipulated/read without the key. It uses URL safe encoding for the keys. Fernet uses 128-bit AES in CBC mode and PKCS7 padding, with HMAC using SHA256 for authentication. The IV is created from os.random().<br><br><b>Key:</b> The key must be 32 bytes (256 bits) encoded with Base64.";
this.infoURL = "https://asecuritysite.com/encryption/fer";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
"name": "Key",
"type": "string",
"value": ""
},
];
}
/**
* @param {String} input
* @param {Object[]} args
* @returns {String}
*/
run(input, args) {
const [secretInput] = args;
try {
const secret = new fernet.Secret(secretInput);
const token = new fernet.Token({
secret: secret,
});
return token.encode(input);
} catch (err) {
throw new OperationError(err);
}
}
}
export default FernetEncrypt;

View File

@ -136,7 +136,7 @@ TestRegister.addApiTests([
it("chef.help: returns multiple results", () => { it("chef.help: returns multiple results", () => {
const result = chef.help("base 64"); const result = chef.help("base 64");
assert.strictEqual(result.length, 11); assert.strictEqual(result.length, 13);
}), }),
it("chef.help: looks in description for matches too", () => { it("chef.help: looks in description for matches too", () => {

View File

@ -0,0 +1,80 @@
/**
* Fernet tests.
*
* @author Karsten Silkenbäumer [github.com/kassi]
* @copyright Karsten Silkenbäumer 2019
* @license Apache-2.0
*/
import TestRegister from "../TestRegister";
TestRegister.addTests([
{
name: "Fernet Decrypt: no input",
input: "",
expectedOutput: "Error: Invalid version",
recipeConfig: [
{
op: "Fernet Decrypt",
args: ["MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI="]
}
],
},
{
name: "Fernet Decrypt: no secret",
input: "gAAAAABce-Tycae8klRxhDX2uenJ-uwV8-A1XZ2HRnfOXlNzkKKfRxviNLlgtemhT_fd1Fw5P_zFUAjd69zaJBQyWppAxVV00SExe77ql8c5n62HYJOnoIU=",
expectedOutput: "Error: Secret must be 32 url-safe base64-encoded bytes.",
recipeConfig: [
{
op: "Fernet Decrypt",
args: [""]
}
],
},
{
name: "Fernet Decrypt: valid arguments",
input: "gAAAAABce-Tycae8klRxhDX2uenJ-uwV8-A1XZ2HRnfOXlNzkKKfRxviNLlgtemhT_fd1Fw5P_zFUAjd69zaJBQyWppAxVV00SExe77ql8c5n62HYJOnoIU=",
expectedOutput: "This is a secret message.\n",
recipeConfig: [
{
op: "Fernet Decrypt",
args: ["VGhpc0lzVGhpcnR5VHdvQ2hhcmFjdGVyc0xvbmdLZXk="]
}
],
}
]);
TestRegister.addTests([
{
name: "Fernet Encrypt: no input",
input: "",
expectedMatch: /^gAAAAABce-[\w-]+={0,2}$/,
recipeConfig: [
{
op: "Fernet Encrypt",
args: ["MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI="]
}
],
},
{
name: "Fernet Encrypt: no secret",
input: "This is a secret message.\n",
expectedOutput: "Error: Secret must be 32 url-safe base64-encoded bytes.",
recipeConfig: [
{
op: "Fernet Encrypt",
args: [""]
}
],
},
{
name: "Fernet Encrypt: valid arguments",
input: "This is a secret message.\n",
expectedMatch: /^gAAAAABce-[\w-]+={0,2}$/,
recipeConfig: [
{
op: "Fernet Encrypt",
args: ["MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI="]
}
],
}
]);