mirror of
https://github.com/gchq/CyberChef.git
synced 2025-05-11 16:51:31 -04:00
Implement PGP encrypt and PGP decrypt operations
This commit is contained in:
parent
7f0ce0da8d
commit
67f94df060
7 changed files with 24726 additions and 30 deletions
|
@ -92,6 +92,8 @@ var Categories = [
|
|||
"Substitute",
|
||||
"Derive PBKDF2 key",
|
||||
"Derive EVP key",
|
||||
"PGP Encrypt",
|
||||
"PGP Decrypt",
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -3148,4 +3148,35 @@ var OperationConfig = {
|
|||
}
|
||||
]
|
||||
},
|
||||
"PGP Encrypt": {
|
||||
description: "Input: An ASCII-Armored PGP public key.<br><br>Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.<br><br>This function relies on OpenPGP.js for the implementation of PGP.<br><br>See more at https://openpgpjs.org/",
|
||||
run: PGP.runEncrypt,
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Public key",
|
||||
type: "text",
|
||||
value: "",
|
||||
},
|
||||
]
|
||||
},
|
||||
"PGP Decrypt": {
|
||||
description: "Input: An ASCII-Armored PGP private key (and optionally, the password needed to decrypt the private key).<br><br>Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.<br><br>This function relies on OpenPGP.js for the implementation of PGP.<br><br>See more at https://openpgpjs.org/",
|
||||
run: PGP.runDecrypt,
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Private key",
|
||||
type: "text",
|
||||
value: "",
|
||||
},
|
||||
{
|
||||
name: "Private key password",
|
||||
type: "text",
|
||||
value: "",
|
||||
},
|
||||
]
|
||||
},
|
||||
};
|
||||
|
|
24051
src/js/lib/openpgp.js
Normal file
24051
src/js/lib/openpgp.js
Normal file
File diff suppressed because it is too large
Load diff
93
src/js/operations/PGP.js
Executable file
93
src/js/operations/PGP.js
Executable file
|
@ -0,0 +1,93 @@
|
|||
/* globals openpgp */
|
||||
|
||||
/**
|
||||
* PGP operations.
|
||||
*
|
||||
* @author tlwr [toby@toby.codes]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*
|
||||
* @namespace
|
||||
*/
|
||||
var PGP = {
|
||||
|
||||
|
||||
/**
|
||||
* Encrypts the input using PGP.
|
||||
*
|
||||
* @param {string} input - plaintext to encrypt
|
||||
* @param {function} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runEncrypt: function (plaintext, args) {
|
||||
var publicKey = args[0];
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
try {
|
||||
var options = {
|
||||
data: plaintext,
|
||||
publicKeys: openpgp.key.readArmored(publicKey).keys,
|
||||
};
|
||||
} catch (error) {
|
||||
reject("Failed to read public key", error);
|
||||
}
|
||||
|
||||
// Timeout is so that UI can update before openpgp blocks thread
|
||||
openpgp.encrypt(options)
|
||||
.then(function(ciphertext) {
|
||||
console.log(ciphertext);
|
||||
resolve(ciphertext.data);
|
||||
})
|
||||
.catch(function(error) {
|
||||
reject("Failed to encrypt input", error);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Decrypts the input using PGP.
|
||||
*
|
||||
* @param {string} input - ciphertext to decrypt
|
||||
* @param {function} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runDecrypt: function (input, args) {
|
||||
var privateKey = args[0],
|
||||
password = args[1];
|
||||
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
try {
|
||||
privateKey = openpgp.key.readArmored(privateKey).keys[0];
|
||||
} catch (error) {
|
||||
reject("Failed to read private key", error);
|
||||
}
|
||||
|
||||
try {
|
||||
if (password && password.length) {
|
||||
privateKey.decrypt(password);
|
||||
}
|
||||
} catch (error) {
|
||||
reject("Failed to decrypt private key", error);
|
||||
}
|
||||
|
||||
try {
|
||||
var options = {
|
||||
message: openpgp.message.readArmored(input),
|
||||
privateKey: privateKey,
|
||||
};
|
||||
} catch (error) {
|
||||
reject("Failed to read input message", error);
|
||||
}
|
||||
|
||||
openpgp.decrypt(options)
|
||||
.then(function(plaintext) {
|
||||
resolve(plaintext.data);
|
||||
})
|
||||
.catch(function(error) {
|
||||
reject("Failed to encrypt input", error);
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
|
@ -106,41 +106,45 @@ HTMLApp.prototype.bake = function(step) {
|
|||
app.setBakingStatus(true);
|
||||
|
||||
try {
|
||||
app.chef.bake(
|
||||
app.getInput(), // The user's input
|
||||
app.getRecipeConfig(), // The configuration of the recipe
|
||||
app.options, // Options set by the user
|
||||
app.progress, // The current position in the recipe
|
||||
step // Whether or not to take one step or execute the whole recipe
|
||||
)
|
||||
.then(function(response) {
|
||||
app.setBakingStatus(false);
|
||||
// This timeout is so the UI has time to update the baking status
|
||||
// before any blocking operations delay it until after the operation.
|
||||
setTimeout(function() {
|
||||
app.chef.bake(
|
||||
app.getInput(), // The user's input
|
||||
app.getRecipeConfig(), // The configuration of the recipe
|
||||
app.options, // Options set by the user
|
||||
app.progress, // The current position in the recipe
|
||||
step // Whether or not to take one step or execute the whole recipe
|
||||
)
|
||||
.then(function(response) {
|
||||
app.setBakingStatus(false);
|
||||
|
||||
if (!response) return;
|
||||
if (response.error) app.handleError(response.error);
|
||||
if (!response) return;
|
||||
if (response.error) app.handleError(response.error);
|
||||
|
||||
app.options = response.options;
|
||||
app.options = response.options;
|
||||
|
||||
if (response.type === "html") {
|
||||
app.dishStr = Utils.stripHtmlTags(response.result, true);
|
||||
} else {
|
||||
app.dishStr = response.result;
|
||||
}
|
||||
if (response.type === "html") {
|
||||
app.dishStr = Utils.stripHtmlTags(response.result, true);
|
||||
} else {
|
||||
app.dishStr = response.result;
|
||||
}
|
||||
|
||||
app.progress = response.progress;
|
||||
app.manager.recipe.updateBreakpointIndicator(response.progress);
|
||||
app.manager.output.set(response.result, response.type, response.duration);
|
||||
app.progress = response.progress;
|
||||
app.manager.recipe.updateBreakpointIndicator(response.progress);
|
||||
app.manager.output.set(response.result, response.type, response.duration);
|
||||
|
||||
// If baking took too long, disable auto-bake
|
||||
if (response.duration > app.options.autoBakeThreshold && app.autoBake_) {
|
||||
app.manager.controls.setAutoBake(false);
|
||||
app.alert("Baking took longer than " + app.options.autoBakeThreshold +
|
||||
"ms, Auto Bake has been disabled.", "warning", 5000);
|
||||
}
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.error("Chef's promise was rejected, this should never occur");
|
||||
});
|
||||
// If baking took too long, disable auto-bake
|
||||
if (response.duration > app.options.autoBakeThreshold && app.autoBake_) {
|
||||
app.manager.controls.setAutoBake(false);
|
||||
app.alert("Baking took longer than " + app.options.autoBakeThreshold +
|
||||
"ms, Auto Bake has been disabled.", "warning", 5000);
|
||||
}
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.error("Chef's promise was rejected, this should never occur");
|
||||
});
|
||||
}, 10);
|
||||
} catch (err) {
|
||||
app.setBakingStatus(false);
|
||||
app.handleError(err);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue