2018-05-23 18:23:03 +01:00
/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*/
2019-07-09 12:23:59 +01:00
import Operation from "../Operation.mjs" ;
import Utils from "../Utils.mjs" ;
import OperationError from "../errors/OperationError.mjs" ;
2020-12-11 17:58:23 +00:00
import forge from "node-forge" ;
2018-05-23 18:23:03 +01:00
/**
* Triple DES Decrypt operation
*/
class TripleDESDecrypt extends Operation {
/**
* TripleDESDecrypt constructor
*/
constructor () {
super ();
this . name = "Triple DES Decrypt" ;
this . module = "Ciphers" ;
2022-03-29 18:01:57 +01:00
this . description = "Triple DES applies DES three times to each block to increase key size.<br><br><b>Key:</b> Triple DES uses a key length of 24 bytes (192 bits).<br>DES uses a key length of 8 bytes (64 bits).<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used as a default." ;
2018-08-21 19:07:13 +01:00
this . infoURL = "https://wikipedia.org/wiki/Triple_DES" ;
2018-05-23 18:23:03 +01: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" ,
2021-03-24 00:58:54 +01:00
"value" : [ "CBC" , "CFB" , "OFB" , "CTR" , "ECB" , "CBC/NoPadding" , "ECB/NoPadding" ]
2018-05-23 18:23:03 +01:00
},
{
"name" : "Input" ,
"type" : "option" ,
"value" : [ "Hex" , "Raw" ]
},
{
"name" : "Output" ,
"type" : "option" ,
"value" : [ "Raw" , "Hex" ]
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run ( input , args ) {
const key = Utils . convertToByteString ( args [ 0 ]. string , args [ 0 ]. option ),
iv = Utils . convertToByteArray ( args [ 1 ]. string , args [ 1 ]. option ),
2021-03-24 00:58:54 +01:00
mode = args [ 2 ]. substring ( 0 , 3 ),
2022-03-29 18:01:57 +01:00
noPadding = args [ 2 ]. endsWith ( "NoPadding" ),
2018-05-23 18:23:03 +01:00
inputType = args [ 3 ],
outputType = args [ 4 ];
if ( key . length !== 24 ) {
2018-05-27 16:13:18 +01:00
throw new OperationError ( `Invalid key length: ${ key . length } bytes
2018-05-23 18:23:03 +01:00
Triple DES uses a key length of 24 bytes (192 bits).
2018-05-27 16:13:18 +01:00
DES uses a key length of 8 bytes (64 bits).` );
2018-05-23 18:23:03 +01:00
}
2019-10-18 11:09:12 +01:00
if ( iv . length !== 8 && mode !== "ECB" ) {
2019-10-16 15:50:37 +01:00
throw new OperationError ( `Invalid IV length: ${ iv . length } bytes
Triple DES uses an IV length of 8 bytes (64 bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).` );
}
2018-05-23 18:23:03 +01:00
input = Utils . convertToByteString ( input , inputType );
const decipher = forge . cipher . createDecipher ( "3DES-" + mode , key );
2022-03-29 18:01:57 +01:00
2021-03-24 00:58:54 +01:00
/* Allow for a "no padding" mode */
2022-03-29 18:01:57 +01:00
if ( noPadding ) {
2021-03-24 00:58:54 +01:00
decipher . mode . unpad = function ( output , options ) {
return true ;
};
}
2022-03-29 18:01:57 +01:00
2018-05-23 18:23:03 +01:00
decipher . start ({ iv : iv });
decipher . update ( forge . util . createBuffer ( input ));
const result = decipher . finish ();
if ( result ) {
return outputType === "Hex" ? decipher . output . toHex () : decipher . output . getBytes ();
} else {
2018-05-27 16:13:18 +01:00
throw new OperationError ( "Unable to decrypt input with these parameters." );
2018-05-23 18:23:03 +01:00
}
}
}
export default TripleDESDecrypt ;