2018-05-14 18:23:16 +00:00
/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*/
import Operation from "../Operation" ;
import Utils from "../Utils" ;
import forge from "node-forge/dist/forge.min.js" ;
2018-05-15 18:01:04 +01:00
import OperationError from "../errors/OperationError" ;
2018-05-14 18:23:16 +00:00
/**
* AES Encrypt operation
*/
class AESEncrypt extends Operation {
/**
* AESEncrypt constructor
*/
constructor () {
super ();
this . name = "AES Encrypt" ;
this . module = "Ciphers" ;
this . description = "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.<br><br><b>Key:</b> The following algorithms will be used based on the size of the key:<ul><li>16 bytes = AES-128</li><li>24 bytes = AES-192</li><li>32 bytes = AES-256</li></ul>You can generate a password-based key using one of the KDF operations.<br><br><b>IV:</b> The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used." ;
2018-08-21 19:07:13 +01:00
this . infoURL = "https://wikipedia.org/wiki/Advanced_Encryption_Standard" ;
2018-05-14 18:23:16 +00:00
this . inputType = "string" ;
this . outputType = "string" ;
this . args = [
{
"name" : "Key" ,
"type" : "toggleString" ,
"value" : "" ,
"toggleValues" : [ "Hex" , "UTF8" , "Latin1" , "Base64" ]
},
{
"name" : "IV" ,
"type" : "toggleString" ,
"value" : "" ,
"toggleValues" : [ "Hex" , "UTF8" , "Latin1" , "Base64" ]
},
{
"name" : "Mode" ,
"type" : "option" ,
"value" : [ "CBC" , "CFB" , "OFB" , "CTR" , "GCM" , "ECB" ]
},
{
"name" : "Input" ,
"type" : "option" ,
"value" : [ "Raw" , "Hex" ]
},
{
"name" : "Output" ,
"type" : "option" ,
"value" : [ "Hex" , "Raw" ]
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
2018-05-15 18:01:04 +01:00
*
* @throws {OperationError} if invalid key length
2018-05-14 18:23:16 +00:00
*/
run ( input , args ) {
const key = Utils . convertToByteArray ( args [ 0 ]. string , args [ 0 ]. option ),
iv = Utils . convertToByteArray ( args [ 1 ]. string , args [ 1 ]. option ),
mode = args [ 2 ],
inputType = args [ 3 ],
outputType = args [ 4 ];
if ([ 16 , 24 , 32 ]. indexOf ( key . length ) < 0 ) {
2018-05-15 18:01:04 +01:00
throw new OperationError ( `Invalid key length: ${ key . length } bytes
2018-05-14 18:23:16 +00:00
The following algorithms will be used based on the size of the key:
16 bytes = AES-128
24 bytes = AES-192
2018-05-15 18:01:04 +01:00
32 bytes = AES-256` );
2018-05-14 18:23:16 +00:00
}
input = Utils . convertToByteString ( input , inputType );
const cipher = forge . cipher . createCipher ( "AES-" + mode , key );
cipher . start ({ iv : iv });
cipher . update ( forge . util . createBuffer ( input ));
cipher . finish ();
if ( outputType === "Hex" ) {
if ( mode === "GCM" ) {
return cipher . output . toHex () + "\n\n" +
"Tag: " + cipher . mode . tag . toHex ();
}
return cipher . output . toHex ();
} else {
if ( mode === "GCM" ) {
return cipher . output . getBytes () + "\n\n" +
"Tag: " + cipher . mode . tag . getBytes ();
}
return cipher . output . getBytes ();
}
}
}
export default AESEncrypt ;