2018-05-14 20:23:16 +02:00
/ * *
* @ author n1474335 [ n1474335 @ gmail . com ]
* @ copyright Crown Copyright 2016
* @ license Apache - 2.0
* /
2019-07-09 13:23:59 +02:00
import Operation from "../Operation.mjs" ;
import Utils from "../Utils.mjs" ;
2020-12-11 18:58:23 +01:00
import forge from "node-forge" ;
2019-07-09 13:23:59 +02:00
import OperationError from "../errors/OperationError.mjs" ;
2018-05-14 20:23:16 +02: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 20:07:13 +02:00
this . infoURL = "https://wikipedia.org/wiki/Advanced_Encryption_Standard" ;
2018-05-14 20:23:16 +02: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" ,
2020-04-07 13:57:32 +02:00
"type" : "argSelector" ,
"value" : [
{
name : "CBC" ,
off : [ 5 ]
} ,
{
name : "CFB" ,
off : [ 5 ]
} ,
{
name : "OFB" ,
off : [ 5 ]
} ,
{
2021-02-02 18:18:35 +01:00
name : "CTR" ,
2020-04-07 13:57:32 +02:00
off : [ 5 ]
} ,
{
name : "GCM" ,
on : [ 5 ]
} ,
{
name : "ECB" ,
off : [ 5 ]
}
]
2018-05-14 20:23:16 +02:00
} ,
{
"name" : "Input" ,
"type" : "option" ,
"value" : [ "Raw" , "Hex" ]
} ,
{
"name" : "Output" ,
"type" : "option" ,
"value" : [ "Hex" , "Raw" ]
2020-04-07 13:57:32 +02:00
} ,
{
"name" : "Additional Authenticated Data" ,
2021-02-22 20:33:52 +01:00
"type" : "toggleString" ,
"value" : "" ,
"toggleValues" : [ "Hex" , "UTF8" , "Latin1" , "Base64" ]
2018-05-14 20:23:16 +02:00
}
] ;
}
/ * *
* @ param { string } input
* @ param { Object [ ] } args
* @ returns { string }
2018-05-15 19:01:04 +02:00
*
* @ throws { OperationError } if invalid key length
2018-05-14 20:23:16 +02:00
* /
run ( input , args ) {
2019-06-04 11:19:00 +02:00
const key = Utils . convertToByteString ( args [ 0 ] . string , args [ 0 ] . option ) ,
iv = Utils . convertToByteString ( args [ 1 ] . string , args [ 1 ] . option ) ,
2018-05-14 20:23:16 +02:00
mode = args [ 2 ] ,
inputType = args [ 3 ] ,
2021-02-02 18:18:35 +01:00
outputType = args [ 4 ] ,
2021-02-22 20:33:52 +01:00
aad = Utils . convertToByteString ( args [ 5 ] . string , args [ 5 ] . option ) ;
2018-05-14 20:23:16 +02:00
if ( [ 16 , 24 , 32 ] . indexOf ( key . length ) < 0 ) {
2018-05-15 19:01:04 +02:00
throw new OperationError ( ` Invalid key length: ${ key . length } bytes
2018-05-14 20:23:16 +02: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 19:01:04 +02:00
32 bytes = AES - 256 ` );
2018-05-14 20:23:16 +02:00
}
input = Utils . convertToByteString ( input , inputType ) ;
const cipher = forge . cipher . createCipher ( "AES-" + mode , key ) ;
2021-02-02 18:18:35 +01:00
cipher . start ( {
iv : iv ,
additionalData : mode === "GCM" ? aad : undefined
} ) ;
2018-05-14 20:23:16 +02:00
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 ;