cyberchef 9.36.1 → 9.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/core/config/Categories.json +2 -0
- package/src/core/config/OperationConfig.json +145 -5
- package/src/core/config/modules/Ciphers.mjs +4 -0
- package/src/core/lib/SM4.mjs +331 -0
- package/src/core/operations/AESDecrypt.mjs +19 -2
- package/src/core/operations/DESDecrypt.mjs +13 -3
- package/src/core/operations/SM4Decrypt.mjs +88 -0
- package/src/core/operations/SM4Encrypt.mjs +88 -0
- package/src/core/operations/TripleDESDecrypt.mjs +12 -3
- package/src/core/operations/index.mjs +4 -0
- package/src/node/index.mjs +10 -0
- package/tests/node/tests/nodeApi.mjs +1 -1
- package/tests/operations/index.mjs +1 -0
- package/tests/operations/tests/SM4.mjs +279 -0
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,10 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
13
13
|
|
|
14
14
|
## Details
|
|
15
15
|
|
|
16
|
+
### [9.37.0] - 2022-03-29
|
|
17
|
+
- 'SM4 Encrypt' and 'SM4 Decrypt' operations added [@swesven] | [#1189]
|
|
18
|
+
- NoPadding options added for CBC and ECB modes in AES, DES and Triple DES Decrypt operations [@swesven] | [#1189]
|
|
19
|
+
|
|
16
20
|
### [9.36.0] - 2022-03-29
|
|
17
21
|
- 'SIGABA' operation added [@hettysymes] | [#934]
|
|
18
22
|
|
|
@@ -284,6 +288,7 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
284
288
|
|
|
285
289
|
|
|
286
290
|
|
|
291
|
+
[9.37.0]: https://github.com/gchq/CyberChef/releases/tag/v9.37.0
|
|
287
292
|
[9.36.0]: https://github.com/gchq/CyberChef/releases/tag/v9.36.0
|
|
288
293
|
[9.35.0]: https://github.com/gchq/CyberChef/releases/tag/v9.35.0
|
|
289
294
|
[9.34.0]: https://github.com/gchq/CyberChef/releases/tag/v9.34.0
|
|
@@ -404,6 +409,7 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
404
409
|
[@john19696]: https://github.com/john19696
|
|
405
410
|
[@t-8ch]: https://github.com/t-8ch
|
|
406
411
|
[@hettysymes]: https://github.com/hettysymes
|
|
412
|
+
[@swesven]: https://github.com/swesven
|
|
407
413
|
|
|
408
414
|
[8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
|
|
409
415
|
[9a33498]: https://github.com/gchq/CyberChef/commit/9a33498fed26a8df9c9f35f39a78a174bf50a513
|
|
@@ -492,6 +498,7 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
492
498
|
[#1049]: https://github.com/gchq/CyberChef/pull/1049
|
|
493
499
|
[#1065]: https://github.com/gchq/CyberChef/pull/1065
|
|
494
500
|
[#1083]: https://github.com/gchq/CyberChef/pull/1083
|
|
501
|
+
[#1189]: https://github.com/gchq/CyberChef/pull/1189
|
|
495
502
|
[#1242]: https://github.com/gchq/CyberChef/pull/1242
|
|
496
503
|
[#1244]: https://github.com/gchq/CyberChef/pull/1244
|
|
497
504
|
[#1313]: https://github.com/gchq/CyberChef/pull/1313
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyberchef",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.37.0",
|
|
4
4
|
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
|
5
5
|
"author": "n1474335 <n1474335@gmail.com>",
|
|
6
6
|
"homepage": "https://gchq.github.io/CyberChef",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
},
|
|
116
116
|
"AES Decrypt": {
|
|
117
117
|
"module": "Ciphers",
|
|
118
|
-
"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><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.<br><br><b>GCM Tag:</b> This field is ignored unless 'GCM' mode is used.",
|
|
118
|
+
"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><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 as a default.<br><br><b>GCM Tag:</b> This field is ignored unless 'GCM' mode is used.",
|
|
119
119
|
"infoURL": "https://wikipedia.org/wiki/Advanced_Encryption_Standard",
|
|
120
120
|
"inputType": "string",
|
|
121
121
|
"outputType": "string",
|
|
@@ -189,6 +189,20 @@
|
|
|
189
189
|
5,
|
|
190
190
|
6
|
|
191
191
|
]
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"name": "CBC/NoPadding",
|
|
195
|
+
"off": [
|
|
196
|
+
5,
|
|
197
|
+
6
|
|
198
|
+
]
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"name": "ECB/NoPadding",
|
|
202
|
+
"off": [
|
|
203
|
+
5,
|
|
204
|
+
6
|
|
205
|
+
]
|
|
192
206
|
}
|
|
193
207
|
]
|
|
194
208
|
},
|
|
@@ -3378,7 +3392,7 @@
|
|
|
3378
3392
|
},
|
|
3379
3393
|
"DES Decrypt": {
|
|
3380
3394
|
"module": "Ciphers",
|
|
3381
|
-
"description": "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.<br><br><b>Key:</b> DES uses a key length of 8 bytes (64 bits).<br>Triple DES uses a key length of 24 bytes (192 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.",
|
|
3395
|
+
"description": "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.<br><br><b>Key:</b> DES uses a key length of 8 bytes (64 bits).<br>Triple DES uses a key length of 24 bytes (192 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.",
|
|
3382
3396
|
"infoURL": "https://wikipedia.org/wiki/Data_Encryption_Standard",
|
|
3383
3397
|
"inputType": "string",
|
|
3384
3398
|
"outputType": "string",
|
|
@@ -3415,7 +3429,9 @@
|
|
|
3415
3429
|
"CFB",
|
|
3416
3430
|
"OFB",
|
|
3417
3431
|
"CTR",
|
|
3418
|
-
"ECB"
|
|
3432
|
+
"ECB",
|
|
3433
|
+
"CBC/NoPadding",
|
|
3434
|
+
"ECB/NoPadding"
|
|
3419
3435
|
]
|
|
3420
3436
|
},
|
|
3421
3437
|
{
|
|
@@ -11874,6 +11890,128 @@
|
|
|
11874
11890
|
}
|
|
11875
11891
|
]
|
|
11876
11892
|
},
|
|
11893
|
+
"SM4 Decrypt": {
|
|
11894
|
+
"module": "Ciphers",
|
|
11895
|
+
"description": "SM4 is a 128-bit block cipher, currently established as a national standard (GB/T 32907-2016) of China.",
|
|
11896
|
+
"infoURL": "https://wikipedia.org/wiki/SM4_(cipher)",
|
|
11897
|
+
"inputType": "string",
|
|
11898
|
+
"outputType": "string",
|
|
11899
|
+
"flowControl": false,
|
|
11900
|
+
"manualBake": false,
|
|
11901
|
+
"args": [
|
|
11902
|
+
{
|
|
11903
|
+
"name": "Key",
|
|
11904
|
+
"type": "toggleString",
|
|
11905
|
+
"value": "",
|
|
11906
|
+
"toggleValues": [
|
|
11907
|
+
"Hex",
|
|
11908
|
+
"UTF8",
|
|
11909
|
+
"Latin1",
|
|
11910
|
+
"Base64"
|
|
11911
|
+
]
|
|
11912
|
+
},
|
|
11913
|
+
{
|
|
11914
|
+
"name": "IV",
|
|
11915
|
+
"type": "toggleString",
|
|
11916
|
+
"value": "",
|
|
11917
|
+
"toggleValues": [
|
|
11918
|
+
"Hex",
|
|
11919
|
+
"UTF8",
|
|
11920
|
+
"Latin1",
|
|
11921
|
+
"Base64"
|
|
11922
|
+
]
|
|
11923
|
+
},
|
|
11924
|
+
{
|
|
11925
|
+
"name": "Mode",
|
|
11926
|
+
"type": "option",
|
|
11927
|
+
"value": [
|
|
11928
|
+
"CBC",
|
|
11929
|
+
"CFB",
|
|
11930
|
+
"OFB",
|
|
11931
|
+
"CTR",
|
|
11932
|
+
"ECB",
|
|
11933
|
+
"CBC/NoPadding",
|
|
11934
|
+
"ECB/NoPadding"
|
|
11935
|
+
]
|
|
11936
|
+
},
|
|
11937
|
+
{
|
|
11938
|
+
"name": "Input",
|
|
11939
|
+
"type": "option",
|
|
11940
|
+
"value": [
|
|
11941
|
+
"Raw",
|
|
11942
|
+
"Hex"
|
|
11943
|
+
]
|
|
11944
|
+
},
|
|
11945
|
+
{
|
|
11946
|
+
"name": "Output",
|
|
11947
|
+
"type": "option",
|
|
11948
|
+
"value": [
|
|
11949
|
+
"Hex",
|
|
11950
|
+
"Raw"
|
|
11951
|
+
]
|
|
11952
|
+
}
|
|
11953
|
+
]
|
|
11954
|
+
},
|
|
11955
|
+
"SM4 Encrypt": {
|
|
11956
|
+
"module": "Ciphers",
|
|
11957
|
+
"description": "SM4 is a 128-bit block cipher, currently established as a national standard (GB/T 32907-2016) of China. Multiple block cipher modes are supported. When using CBC or ECB mode, the PKCS#7 padding scheme is used.",
|
|
11958
|
+
"infoURL": "https://wikipedia.org/wiki/SM4_(cipher)",
|
|
11959
|
+
"inputType": "string",
|
|
11960
|
+
"outputType": "string",
|
|
11961
|
+
"flowControl": false,
|
|
11962
|
+
"manualBake": false,
|
|
11963
|
+
"args": [
|
|
11964
|
+
{
|
|
11965
|
+
"name": "Key",
|
|
11966
|
+
"type": "toggleString",
|
|
11967
|
+
"value": "",
|
|
11968
|
+
"toggleValues": [
|
|
11969
|
+
"Hex",
|
|
11970
|
+
"UTF8",
|
|
11971
|
+
"Latin1",
|
|
11972
|
+
"Base64"
|
|
11973
|
+
]
|
|
11974
|
+
},
|
|
11975
|
+
{
|
|
11976
|
+
"name": "IV",
|
|
11977
|
+
"type": "toggleString",
|
|
11978
|
+
"value": "",
|
|
11979
|
+
"toggleValues": [
|
|
11980
|
+
"Hex",
|
|
11981
|
+
"UTF8",
|
|
11982
|
+
"Latin1",
|
|
11983
|
+
"Base64"
|
|
11984
|
+
]
|
|
11985
|
+
},
|
|
11986
|
+
{
|
|
11987
|
+
"name": "Mode",
|
|
11988
|
+
"type": "option",
|
|
11989
|
+
"value": [
|
|
11990
|
+
"CBC",
|
|
11991
|
+
"CFB",
|
|
11992
|
+
"OFB",
|
|
11993
|
+
"CTR",
|
|
11994
|
+
"ECB"
|
|
11995
|
+
]
|
|
11996
|
+
},
|
|
11997
|
+
{
|
|
11998
|
+
"name": "Input",
|
|
11999
|
+
"type": "option",
|
|
12000
|
+
"value": [
|
|
12001
|
+
"Raw",
|
|
12002
|
+
"Hex"
|
|
12003
|
+
]
|
|
12004
|
+
},
|
|
12005
|
+
{
|
|
12006
|
+
"name": "Output",
|
|
12007
|
+
"type": "option",
|
|
12008
|
+
"value": [
|
|
12009
|
+
"Hex",
|
|
12010
|
+
"Raw"
|
|
12011
|
+
]
|
|
12012
|
+
}
|
|
12013
|
+
]
|
|
12014
|
+
},
|
|
11877
12015
|
"SQL Beautify": {
|
|
11878
12016
|
"module": "Code",
|
|
11879
12017
|
"description": "Indents and prettifies Structured Query Language (SQL) code.",
|
|
@@ -15066,7 +15204,7 @@
|
|
|
15066
15204
|
},
|
|
15067
15205
|
"Triple DES Decrypt": {
|
|
15068
15206
|
"module": "Ciphers",
|
|
15069
|
-
"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.",
|
|
15207
|
+
"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.",
|
|
15070
15208
|
"infoURL": "https://wikipedia.org/wiki/Triple_DES",
|
|
15071
15209
|
"inputType": "string",
|
|
15072
15210
|
"outputType": "string",
|
|
@@ -15103,7 +15241,9 @@
|
|
|
15103
15241
|
"CFB",
|
|
15104
15242
|
"OFB",
|
|
15105
15243
|
"CTR",
|
|
15106
|
-
"ECB"
|
|
15244
|
+
"ECB",
|
|
15245
|
+
"CBC/NoPadding",
|
|
15246
|
+
"ECB/NoPadding"
|
|
15107
15247
|
]
|
|
15108
15248
|
},
|
|
15109
15249
|
{
|
|
@@ -32,6 +32,8 @@ import RSASign from "../../operations/RSASign.mjs";
|
|
|
32
32
|
import RSAVerify from "../../operations/RSAVerify.mjs";
|
|
33
33
|
import RailFenceCipherDecode from "../../operations/RailFenceCipherDecode.mjs";
|
|
34
34
|
import RailFenceCipherEncode from "../../operations/RailFenceCipherEncode.mjs";
|
|
35
|
+
import SM4Decrypt from "../../operations/SM4Decrypt.mjs";
|
|
36
|
+
import SM4Encrypt from "../../operations/SM4Encrypt.mjs";
|
|
35
37
|
import TripleDESDecrypt from "../../operations/TripleDESDecrypt.mjs";
|
|
36
38
|
import TripleDESEncrypt from "../../operations/TripleDESEncrypt.mjs";
|
|
37
39
|
import VigenèreDecode from "../../operations/VigenèreDecode.mjs";
|
|
@@ -67,6 +69,8 @@ OpModules.Ciphers = {
|
|
|
67
69
|
"RSA Verify": RSAVerify,
|
|
68
70
|
"Rail Fence Cipher Decode": RailFenceCipherDecode,
|
|
69
71
|
"Rail Fence Cipher Encode": RailFenceCipherEncode,
|
|
72
|
+
"SM4 Decrypt": SM4Decrypt,
|
|
73
|
+
"SM4 Encrypt": SM4Encrypt,
|
|
70
74
|
"Triple DES Decrypt": TripleDESDecrypt,
|
|
71
75
|
"Triple DES Encrypt": TripleDESEncrypt,
|
|
72
76
|
"Vigenère Decode": VigenèreDecode,
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Complete implementation of SM4 cipher encryption/decryption with
|
|
3
|
+
* ECB, CBC, CFB, OFB, CTR block modes.
|
|
4
|
+
* These modes are specified in IETF draft-ribose-cfrg-sm4-09, see:
|
|
5
|
+
* https://tools.ietf.org/id/draft-ribose-cfrg-sm4-09.html
|
|
6
|
+
* for details.
|
|
7
|
+
*
|
|
8
|
+
* Follows spec from Cryptography Standardization Technical Comittee:
|
|
9
|
+
* http://www.gmbz.org.cn/upload/2018-04-04/1522788048733065051.pdf
|
|
10
|
+
*
|
|
11
|
+
* @author swesven
|
|
12
|
+
* @copyright 2021
|
|
13
|
+
* @license Apache-2.0
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import OperationError from "../errors/OperationError.mjs";
|
|
17
|
+
|
|
18
|
+
/** Number of rounds */
|
|
19
|
+
const NROUNDS = 32;
|
|
20
|
+
|
|
21
|
+
/** block size in bytes */
|
|
22
|
+
const BLOCKSIZE = 16;
|
|
23
|
+
|
|
24
|
+
/** The S box, 256 8-bit values */
|
|
25
|
+
const Sbox = [
|
|
26
|
+
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
|
|
27
|
+
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
|
|
28
|
+
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
|
|
29
|
+
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
|
|
30
|
+
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
|
|
31
|
+
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
|
|
32
|
+
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
|
|
33
|
+
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
|
|
34
|
+
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
|
|
35
|
+
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
|
|
36
|
+
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
|
|
37
|
+
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
|
|
38
|
+
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
|
|
39
|
+
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
|
|
40
|
+
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
|
|
41
|
+
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
/** "Fixed parameter CK" used in key expansion */
|
|
45
|
+
const CK = [
|
|
46
|
+
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
|
|
47
|
+
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
|
|
48
|
+
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
|
|
49
|
+
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
|
|
50
|
+
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
|
|
51
|
+
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
|
|
52
|
+
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
|
|
53
|
+
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
/** "System parameter FK" */
|
|
57
|
+
const FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc];
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Rotating 32-bit shift left
|
|
61
|
+
*
|
|
62
|
+
* (Note that although JS integers are stored in doubles and thus have 53 bits,
|
|
63
|
+
* the JS bitwise operations are 32-bit)
|
|
64
|
+
*/
|
|
65
|
+
function ROL(i, n) {
|
|
66
|
+
return (i << n) | (i >>> (32 - n));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Linear transformation L
|
|
71
|
+
*
|
|
72
|
+
* @param {integer} b - a 32 bit integer
|
|
73
|
+
*/
|
|
74
|
+
function transformL(b) {
|
|
75
|
+
/* Replace each of the 4 bytes in b with the value at its offset in the Sbox */
|
|
76
|
+
b = (Sbox[(b >>> 24) & 0xFF] << 24) | (Sbox[(b >>> 16) & 0xFF] << 16) |
|
|
77
|
+
(Sbox[(b >>> 8) & 0xFF] << 8) | Sbox[b & 0xFF];
|
|
78
|
+
/* circular rotate and xor */
|
|
79
|
+
return b ^ ROL(b, 2) ^ ROL(b, 10) ^ ROL(b, 18) ^ ROL(b, 24);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Linear transformation L'
|
|
84
|
+
*
|
|
85
|
+
* @param {integer} b - a 32 bit integer
|
|
86
|
+
*/
|
|
87
|
+
function transformLprime(b) {
|
|
88
|
+
/* Replace each of the 4 bytes in b with the value at its offset in the Sbox */
|
|
89
|
+
b = (Sbox[(b >>> 24) & 0xFF] << 24) | (Sbox[(b >>> 16) & 0xFF] << 16) |
|
|
90
|
+
(Sbox[(b >>> 8) & 0xFF] << 8) | Sbox[b & 0xFF];
|
|
91
|
+
return b ^ ROL(b, 13) ^ ROL(b, 23); /* circular rotate and XOR */
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Initialize the round key
|
|
96
|
+
*/
|
|
97
|
+
function initSM4RoundKey(rawkey) {
|
|
98
|
+
const K = rawkey.map((a, i) => a ^ FK[i]); /* K = rawkey ^ FK */
|
|
99
|
+
const roundKey = [];
|
|
100
|
+
for (let i = 0; i < 32; i++)
|
|
101
|
+
roundKey[i] = K[i + 4] = K[i] ^ transformLprime(K[i + 1] ^ K[i + 2] ^ K[i + 3] ^ CK[i]);
|
|
102
|
+
return roundKey;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Encrypts/decrypts a single block X (4 32-bit values) with a prepared round key.
|
|
107
|
+
*
|
|
108
|
+
* @param {intArray} X - A cleartext block.
|
|
109
|
+
* @param {intArray} roundKey - The round key from initSMRoundKey for encrypting (reversed for decrypting).
|
|
110
|
+
* @returns {byteArray} - The cipher text.
|
|
111
|
+
*/
|
|
112
|
+
function encryptBlockSM4(X, roundKey) {
|
|
113
|
+
for (let i = 0; i < NROUNDS; i++)
|
|
114
|
+
X[i + 4] = X[i] ^ transformL(X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ roundKey[i]);
|
|
115
|
+
return [X[35], X[34], X[33], X[32]];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Takes 16 bytes from an offset in an array and returns an array of 4 32-bit Big-Endian values.
|
|
120
|
+
* (DataView won't work portably here as we need Big-Endian)
|
|
121
|
+
*
|
|
122
|
+
* @param {byteArray} bArray - the array of bytes
|
|
123
|
+
* @param {integer} offset - starting offset in the array; 15 bytes must follow it.
|
|
124
|
+
*/
|
|
125
|
+
function bytesToInts(bArray, offs=0) {
|
|
126
|
+
let offset = offs;
|
|
127
|
+
const A = (bArray[offset] << 24) | (bArray[offset + 1] << 16) | (bArray[offset + 2] << 8) | bArray[offset + 3];
|
|
128
|
+
offset += 4;
|
|
129
|
+
const B = (bArray[offset] << 24) | (bArray[offset + 1] << 16) | (bArray[offset + 2] << 8) | bArray[offset + 3];
|
|
130
|
+
offset += 4;
|
|
131
|
+
const C = (bArray[offset] << 24) | (bArray[offset + 1] << 16) | (bArray[offset + 2] << 8) | bArray[offset + 3];
|
|
132
|
+
offset += 4;
|
|
133
|
+
const D = (bArray[offset] << 24) | (bArray[offset + 1] << 16) | (bArray[offset + 2] << 8) | bArray[offset + 3];
|
|
134
|
+
return [A, B, C, D];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Inverse of bytesToInts above; takes an array of 32-bit integers and turns it into an array of bytes.
|
|
139
|
+
* Again, Big-Endian order.
|
|
140
|
+
*/
|
|
141
|
+
function intsToBytes(ints) {
|
|
142
|
+
const bArr = [];
|
|
143
|
+
for (let i = 0; i < ints.length; i++) {
|
|
144
|
+
bArr.push((ints[i] >> 24) & 0xFF);
|
|
145
|
+
bArr.push((ints[i] >> 16) & 0xFF);
|
|
146
|
+
bArr.push((ints[i] >> 8) & 0xFF);
|
|
147
|
+
bArr.push(ints[i] & 0xFF);
|
|
148
|
+
}
|
|
149
|
+
return bArr;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Encrypt using SM4 using a given block cipher mode.
|
|
154
|
+
*
|
|
155
|
+
* @param {byteArray} message - The clear text message; any length under 32 Gb or so.
|
|
156
|
+
* @param {byteArray} key - The cipher key, 16 bytes.
|
|
157
|
+
* @param {byteArray} iv - The IV or nonce, 16 bytes (not used with ECB mode)
|
|
158
|
+
* @param {string} mode - The block cipher mode "CBC", "ECB", "CFB", "OFB", "CTR".
|
|
159
|
+
* @param {boolean} noPadding - Don't add PKCS#7 padding if set.
|
|
160
|
+
* @returns {byteArray} - The cipher text.
|
|
161
|
+
*/
|
|
162
|
+
export function encryptSM4(message, key, iv, mode="ECB", noPadding=false) {
|
|
163
|
+
const messageLength = message.length;
|
|
164
|
+
if (messageLength === 0)
|
|
165
|
+
return [];
|
|
166
|
+
const roundKey = initSM4RoundKey(bytesToInts(key, 0));
|
|
167
|
+
|
|
168
|
+
/* Pad with PKCS#7 if requested for ECB/CBC else add zeroes (which are sliced off at the end) */
|
|
169
|
+
let padByte = 0;
|
|
170
|
+
let nPadding = 16 - (message.length & 0xF);
|
|
171
|
+
if (mode === "ECB" || mode === "CBC") {
|
|
172
|
+
if (noPadding) {
|
|
173
|
+
if (nPadding !== 16)
|
|
174
|
+
throw new OperationError(`No padding requested in ${mode} mode but input is not a 16-byte multiple.`);
|
|
175
|
+
nPadding = 0;
|
|
176
|
+
} else
|
|
177
|
+
padByte = nPadding;
|
|
178
|
+
}
|
|
179
|
+
for (let i = 0; i < nPadding; i++)
|
|
180
|
+
message.push(padByte);
|
|
181
|
+
|
|
182
|
+
const cipherText = [];
|
|
183
|
+
switch (mode) {
|
|
184
|
+
case "ECB":
|
|
185
|
+
for (let i = 0; i < message.length; i += BLOCKSIZE)
|
|
186
|
+
Array.prototype.push.apply(cipherText, intsToBytes(encryptBlockSM4(bytesToInts(message, i), roundKey)));
|
|
187
|
+
break;
|
|
188
|
+
case "CBC":
|
|
189
|
+
iv = bytesToInts(iv, 0);
|
|
190
|
+
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
|
191
|
+
const block = bytesToInts(message, i);
|
|
192
|
+
block[0] ^= iv[0]; block[1] ^= iv[1];
|
|
193
|
+
block[2] ^= iv[2]; block[3] ^= iv[3];
|
|
194
|
+
iv = encryptBlockSM4(block, roundKey);
|
|
195
|
+
Array.prototype.push.apply(cipherText, intsToBytes(iv));
|
|
196
|
+
}
|
|
197
|
+
break;
|
|
198
|
+
case "CFB":
|
|
199
|
+
iv = bytesToInts(iv, 0);
|
|
200
|
+
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
|
201
|
+
iv = encryptBlockSM4(iv, roundKey);
|
|
202
|
+
const block = bytesToInts(message, i);
|
|
203
|
+
block[0] ^= iv[0]; block[1] ^= iv[1];
|
|
204
|
+
block[2] ^= iv[2]; block[3] ^= iv[3];
|
|
205
|
+
Array.prototype.push.apply(cipherText, intsToBytes(block));
|
|
206
|
+
iv = block;
|
|
207
|
+
}
|
|
208
|
+
break;
|
|
209
|
+
case "OFB":
|
|
210
|
+
iv = bytesToInts(iv, 0);
|
|
211
|
+
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
|
212
|
+
iv = encryptBlockSM4(iv, roundKey);
|
|
213
|
+
const block = bytesToInts(message, i);
|
|
214
|
+
block[0] ^= iv[0]; block[1] ^= iv[1];
|
|
215
|
+
block[2] ^= iv[2]; block[3] ^= iv[3];
|
|
216
|
+
Array.prototype.push.apply(cipherText, intsToBytes(block));
|
|
217
|
+
}
|
|
218
|
+
break;
|
|
219
|
+
case "CTR":
|
|
220
|
+
iv = bytesToInts(iv, 0);
|
|
221
|
+
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
|
222
|
+
let iv2 = [...iv]; /* containing the IV + counter */
|
|
223
|
+
iv2[3] += (i >> 4);/* Using a 32 bit counter here. 64 Gb encrypts should be enough for everyone. */
|
|
224
|
+
iv2 = encryptBlockSM4(iv2, roundKey);
|
|
225
|
+
const block = bytesToInts(message, i);
|
|
226
|
+
block[0] ^= iv2[0]; block[1] ^= iv2[1];
|
|
227
|
+
block[2] ^= iv2[2]; block[3] ^= iv2[3];
|
|
228
|
+
Array.prototype.push.apply(cipherText, intsToBytes(block));
|
|
229
|
+
}
|
|
230
|
+
break;
|
|
231
|
+
default:
|
|
232
|
+
throw new OperationError("Invalid block cipher mode: "+mode);
|
|
233
|
+
}
|
|
234
|
+
if (mode !== "ECB" && mode !== "CBC")
|
|
235
|
+
return cipherText.slice(0, messageLength);
|
|
236
|
+
return cipherText;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Decrypt using SM4 using a given block cipher mode.
|
|
241
|
+
*
|
|
242
|
+
* @param {byteArray} cipherText - The ciphertext
|
|
243
|
+
* @param {byteArray} key - The cipher key, 16 bytes.
|
|
244
|
+
* @param {byteArray} iv - The IV or nonce, 16 bytes (not used with ECB mode)
|
|
245
|
+
* @param {string} mode - The block cipher mode "CBC", "ECB", "CFB", "OFB", "CTR"
|
|
246
|
+
* @param {boolean] ignorePadding - If true, ignore padding issues in ECB/CBC mode.
|
|
247
|
+
* @returns {byteArray} - The cipher text.
|
|
248
|
+
*/
|
|
249
|
+
export function decryptSM4(cipherText, key, iv, mode="ECB", ignorePadding=false) {
|
|
250
|
+
const originalLength = cipherText.length;
|
|
251
|
+
if (originalLength === 0)
|
|
252
|
+
return [];
|
|
253
|
+
let roundKey = initSM4RoundKey(bytesToInts(key, 0));
|
|
254
|
+
|
|
255
|
+
if (mode === "ECB" || mode === "CBC") {
|
|
256
|
+
/* Init decryption key */
|
|
257
|
+
roundKey = roundKey.reverse();
|
|
258
|
+
if ((originalLength & 0xF) !== 0 && !ignorePadding)
|
|
259
|
+
throw new OperationError(`With ECB or CBC modes, the input must be divisible into 16 byte blocks. (${cipherText.length & 0xF} bytes extra)`);
|
|
260
|
+
} else { /* Pad dummy bytes for other modes, chop them off at the end */
|
|
261
|
+
while ((cipherText.length & 0xF) !== 0)
|
|
262
|
+
cipherText.push(0);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const clearText = [];
|
|
266
|
+
switch (mode) {
|
|
267
|
+
case "ECB":
|
|
268
|
+
for (let i = 0; i < cipherText.length; i += BLOCKSIZE)
|
|
269
|
+
Array.prototype.push.apply(clearText, intsToBytes(encryptBlockSM4(bytesToInts(cipherText, i), roundKey)));
|
|
270
|
+
break;
|
|
271
|
+
case "CBC":
|
|
272
|
+
iv = bytesToInts(iv, 0);
|
|
273
|
+
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
|
274
|
+
const block = encryptBlockSM4(bytesToInts(cipherText, i), roundKey);
|
|
275
|
+
block[0] ^= iv[0]; block[1] ^= iv[1];
|
|
276
|
+
block[2] ^= iv[2]; block[3] ^= iv[3];
|
|
277
|
+
Array.prototype.push.apply(clearText, intsToBytes(block));
|
|
278
|
+
iv = bytesToInts(cipherText, i);
|
|
279
|
+
}
|
|
280
|
+
break;
|
|
281
|
+
case "CFB":
|
|
282
|
+
iv = bytesToInts(iv, 0);
|
|
283
|
+
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
|
284
|
+
iv = encryptBlockSM4(iv, roundKey);
|
|
285
|
+
const block = bytesToInts(cipherText, i);
|
|
286
|
+
block[0] ^= iv[0]; block[1] ^= iv[1];
|
|
287
|
+
block[2] ^= iv[2]; block[3] ^= iv[3];
|
|
288
|
+
Array.prototype.push.apply(clearText, intsToBytes(block));
|
|
289
|
+
iv = bytesToInts(cipherText, i);
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
case "OFB":
|
|
293
|
+
iv = bytesToInts(iv, 0);
|
|
294
|
+
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
|
295
|
+
iv = encryptBlockSM4(iv, roundKey);
|
|
296
|
+
const block = bytesToInts(cipherText, i);
|
|
297
|
+
block[0] ^= iv[0]; block[1] ^= iv[1];
|
|
298
|
+
block[2] ^= iv[2]; block[3] ^= iv[3];
|
|
299
|
+
Array.prototype.push.apply(clearText, intsToBytes(block));
|
|
300
|
+
}
|
|
301
|
+
break;
|
|
302
|
+
case "CTR":
|
|
303
|
+
iv = bytesToInts(iv, 0);
|
|
304
|
+
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
|
305
|
+
let iv2 = [...iv]; /* containing the IV + counter */
|
|
306
|
+
iv2[3] += (i >> 4);/* Using a 32 bit counter here. 64 Gb encrypts should be enough for everyone. */
|
|
307
|
+
iv2 = encryptBlockSM4(iv2, roundKey);
|
|
308
|
+
const block = bytesToInts(cipherText, i);
|
|
309
|
+
block[0] ^= iv2[0]; block[1] ^= iv2[1];
|
|
310
|
+
block[2] ^= iv2[2]; block[3] ^= iv2[3];
|
|
311
|
+
Array.prototype.push.apply(clearText, intsToBytes(block));
|
|
312
|
+
}
|
|
313
|
+
break;
|
|
314
|
+
default:
|
|
315
|
+
throw new OperationError(`Invalid block cipher mode: ${mode}`);
|
|
316
|
+
}
|
|
317
|
+
/* Check PKCS#7 padding */
|
|
318
|
+
if (mode === "ECB" || mode === "CBC") {
|
|
319
|
+
if (ignorePadding)
|
|
320
|
+
return clearText;
|
|
321
|
+
const padByte = clearText[clearText.length - 1];
|
|
322
|
+
if (padByte > 16)
|
|
323
|
+
throw new OperationError("Invalid PKCS#7 padding.");
|
|
324
|
+
for (let i = 0; i < padByte; i++)
|
|
325
|
+
if (clearText[clearText.length -i - 1] !== padByte)
|
|
326
|
+
throw new OperationError("Invalid PKCS#7 padding.");
|
|
327
|
+
return clearText.slice(0, clearText.length - padByte);
|
|
328
|
+
}
|
|
329
|
+
return clearText.slice(0, originalLength);
|
|
330
|
+
}
|
|
331
|
+
|
|
@@ -22,7 +22,7 @@ class AESDecrypt extends Operation {
|
|
|
22
22
|
|
|
23
23
|
this.name = "AES Decrypt";
|
|
24
24
|
this.module = "Ciphers";
|
|
25
|
-
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><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.<br><br><b>GCM Tag:</b> This field is ignored unless 'GCM' mode is used.";
|
|
25
|
+
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><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 as a default.<br><br><b>GCM Tag:</b> This field is ignored unless 'GCM' mode is used.";
|
|
26
26
|
this.infoURL = "https://wikipedia.org/wiki/Advanced_Encryption_Standard";
|
|
27
27
|
this.inputType = "string";
|
|
28
28
|
this.outputType = "string";
|
|
@@ -66,6 +66,14 @@ class AESDecrypt extends Operation {
|
|
|
66
66
|
{
|
|
67
67
|
name: "ECB",
|
|
68
68
|
off: [5, 6]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "CBC/NoPadding",
|
|
72
|
+
off: [5, 6]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: "ECB/NoPadding",
|
|
76
|
+
off: [5, 6]
|
|
69
77
|
}
|
|
70
78
|
]
|
|
71
79
|
},
|
|
@@ -104,7 +112,8 @@ class AESDecrypt extends Operation {
|
|
|
104
112
|
run(input, args) {
|
|
105
113
|
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
|
106
114
|
iv = Utils.convertToByteString(args[1].string, args[1].option),
|
|
107
|
-
mode = args[2],
|
|
115
|
+
mode = args[2].substring(0, 3),
|
|
116
|
+
noPadding = args[2].endsWith("NoPadding"),
|
|
108
117
|
inputType = args[3],
|
|
109
118
|
outputType = args[4],
|
|
110
119
|
gcmTag = Utils.convertToByteString(args[5].string, args[5].option),
|
|
@@ -122,6 +131,14 @@ The following algorithms will be used based on the size of the key:
|
|
|
122
131
|
input = Utils.convertToByteString(input, inputType);
|
|
123
132
|
|
|
124
133
|
const decipher = forge.cipher.createDecipher("AES-" + mode, key);
|
|
134
|
+
|
|
135
|
+
/* Allow for a "no padding" mode */
|
|
136
|
+
if (noPadding) {
|
|
137
|
+
decipher.mode.unpad = function(output, options) {
|
|
138
|
+
return true;
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
125
142
|
decipher.start({
|
|
126
143
|
iv: iv.length === 0 ? "" : iv,
|
|
127
144
|
tag: mode === "GCM" ? gcmTag : undefined,
|
|
@@ -22,7 +22,7 @@ class DESDecrypt extends Operation {
|
|
|
22
22
|
|
|
23
23
|
this.name = "DES Decrypt";
|
|
24
24
|
this.module = "Ciphers";
|
|
25
|
-
this.description = "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.<br><br><b>Key:</b> DES uses a key length of 8 bytes (64 bits).<br>Triple DES uses a key length of 24 bytes (192 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.";
|
|
25
|
+
this.description = "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.<br><br><b>Key:</b> DES uses a key length of 8 bytes (64 bits).<br>Triple DES uses a key length of 24 bytes (192 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.";
|
|
26
26
|
this.infoURL = "https://wikipedia.org/wiki/Data_Encryption_Standard";
|
|
27
27
|
this.inputType = "string";
|
|
28
28
|
this.outputType = "string";
|
|
@@ -42,7 +42,7 @@ class DESDecrypt extends Operation {
|
|
|
42
42
|
{
|
|
43
43
|
"name": "Mode",
|
|
44
44
|
"type": "option",
|
|
45
|
-
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
|
|
45
|
+
"value": ["CBC", "CFB", "OFB", "CTR", "ECB", "CBC/NoPadding", "ECB/NoPadding"]
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"name": "Input",
|
|
@@ -65,7 +65,9 @@ class DESDecrypt extends Operation {
|
|
|
65
65
|
run(input, args) {
|
|
66
66
|
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
|
67
67
|
iv = Utils.convertToByteArray(args[1].string, args[1].option),
|
|
68
|
-
|
|
68
|
+
mode = args[2].substring(0, 3),
|
|
69
|
+
noPadding = args[2].endsWith("NoPadding"),
|
|
70
|
+
[,,, inputType, outputType] = args;
|
|
69
71
|
|
|
70
72
|
if (key.length !== 8) {
|
|
71
73
|
throw new OperationError(`Invalid key length: ${key.length} bytes
|
|
@@ -83,6 +85,14 @@ Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
|
|
83
85
|
input = Utils.convertToByteString(input, inputType);
|
|
84
86
|
|
|
85
87
|
const decipher = forge.cipher.createDecipher("DES-" + mode, key);
|
|
88
|
+
|
|
89
|
+
/* Allow for a "no padding" mode */
|
|
90
|
+
if (noPadding) {
|
|
91
|
+
decipher.mode.unpad = function(output, options) {
|
|
92
|
+
return true;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
86
96
|
decipher.start({iv: iv});
|
|
87
97
|
decipher.update(forge.util.createBuffer(input));
|
|
88
98
|
const result = decipher.finish();
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author swesven
|
|
3
|
+
* @copyright 2021
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
import Utils from "../Utils.mjs";
|
|
9
|
+
import OperationError from "../errors/OperationError.mjs";
|
|
10
|
+
import { toHex } from "../lib/Hex.mjs";
|
|
11
|
+
import { decryptSM4 } from "../lib/SM4.mjs";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* SM4 Decrypt operation
|
|
15
|
+
*/
|
|
16
|
+
class SM4Decrypt extends Operation {
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* SM4Encrypt constructor
|
|
20
|
+
*/
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
|
|
24
|
+
this.name = "SM4 Decrypt";
|
|
25
|
+
this.module = "Ciphers";
|
|
26
|
+
this.description = "SM4 is a 128-bit block cipher, currently established as a national standard (GB/T 32907-2016) of China.";
|
|
27
|
+
this.infoURL = "https://wikipedia.org/wiki/SM4_(cipher)";
|
|
28
|
+
this.inputType = "string";
|
|
29
|
+
this.outputType = "string";
|
|
30
|
+
this.args = [
|
|
31
|
+
{
|
|
32
|
+
"name": "Key",
|
|
33
|
+
"type": "toggleString",
|
|
34
|
+
"value": "",
|
|
35
|
+
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "IV",
|
|
39
|
+
"type": "toggleString",
|
|
40
|
+
"value": "",
|
|
41
|
+
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "Mode",
|
|
45
|
+
"type": "option",
|
|
46
|
+
"value": ["CBC", "CFB", "OFB", "CTR", "ECB", "CBC/NoPadding", "ECB/NoPadding"]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "Input",
|
|
50
|
+
"type": "option",
|
|
51
|
+
"value": ["Raw", "Hex"]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "Output",
|
|
55
|
+
"type": "option",
|
|
56
|
+
"value": ["Hex", "Raw"]
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {string} input
|
|
63
|
+
* @param {Object[]} args
|
|
64
|
+
* @returns {string}
|
|
65
|
+
*/
|
|
66
|
+
run(input, args) {
|
|
67
|
+
const key = Utils.convertToByteArray(args[0].string, args[0].option),
|
|
68
|
+
iv = Utils.convertToByteArray(args[1].string, args[1].option),
|
|
69
|
+
[,, mode, inputType, outputType] = args;
|
|
70
|
+
|
|
71
|
+
if (key.length !== 16)
|
|
72
|
+
throw new OperationError(`Invalid key length: ${key.length} bytes
|
|
73
|
+
|
|
74
|
+
SM4 uses a key length of 16 bytes (128 bits).`);
|
|
75
|
+
if (iv.length !== 16 && !mode.startsWith("ECB"))
|
|
76
|
+
throw new OperationError(`Invalid IV length: ${iv.length} bytes
|
|
77
|
+
|
|
78
|
+
SM4 uses an IV length of 16 bytes (128 bits).
|
|
79
|
+
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
|
80
|
+
|
|
81
|
+
input = Utils.convertToByteArray(input, inputType);
|
|
82
|
+
const output = decryptSM4(input, key, iv, mode.substring(0, 3), mode.endsWith("NoPadding"));
|
|
83
|
+
return outputType === "Hex" ? toHex(output) : Utils.byteArrayToUtf8(output);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export default SM4Decrypt;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author swesven
|
|
3
|
+
* @copyright 2021
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
import Utils from "../Utils.mjs";
|
|
9
|
+
import OperationError from "../errors/OperationError.mjs";
|
|
10
|
+
import { toHex } from "../lib/Hex.mjs";
|
|
11
|
+
import { encryptSM4 } from "../lib/SM4.mjs";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* SM4 Encrypt operation
|
|
15
|
+
*/
|
|
16
|
+
class SM4Encrypt extends Operation {
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* SM4Encrypt constructor
|
|
20
|
+
*/
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
|
|
24
|
+
this.name = "SM4 Encrypt";
|
|
25
|
+
this.module = "Ciphers";
|
|
26
|
+
this.description = "SM4 is a 128-bit block cipher, currently established as a national standard (GB/T 32907-2016) of China. Multiple block cipher modes are supported. When using CBC or ECB mode, the PKCS#7 padding scheme is used.";
|
|
27
|
+
this.infoURL = "https://wikipedia.org/wiki/SM4_(cipher)";
|
|
28
|
+
this.inputType = "string";
|
|
29
|
+
this.outputType = "string";
|
|
30
|
+
this.args = [
|
|
31
|
+
{
|
|
32
|
+
"name": "Key",
|
|
33
|
+
"type": "toggleString",
|
|
34
|
+
"value": "",
|
|
35
|
+
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "IV",
|
|
39
|
+
"type": "toggleString",
|
|
40
|
+
"value": "",
|
|
41
|
+
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "Mode",
|
|
45
|
+
"type": "option",
|
|
46
|
+
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "Input",
|
|
50
|
+
"type": "option",
|
|
51
|
+
"value": ["Raw", "Hex"]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "Output",
|
|
55
|
+
"type": "option",
|
|
56
|
+
"value": ["Hex", "Raw"]
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {string} input
|
|
63
|
+
* @param {Object[]} args
|
|
64
|
+
* @returns {string}
|
|
65
|
+
*/
|
|
66
|
+
run(input, args) {
|
|
67
|
+
const key = Utils.convertToByteArray(args[0].string, args[0].option),
|
|
68
|
+
iv = Utils.convertToByteArray(args[1].string, args[1].option),
|
|
69
|
+
[,, mode, inputType, outputType] = args;
|
|
70
|
+
|
|
71
|
+
if (key.length !== 16)
|
|
72
|
+
throw new OperationError(`Invalid key length: ${key.length} bytes
|
|
73
|
+
|
|
74
|
+
SM4 uses a key length of 16 bytes (128 bits).`);
|
|
75
|
+
if (iv.length !== 16 && !mode.startsWith("ECB"))
|
|
76
|
+
throw new OperationError(`Invalid IV length: ${iv.length} bytes
|
|
77
|
+
|
|
78
|
+
SM4 uses an IV length of 16 bytes (128 bits).
|
|
79
|
+
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
|
80
|
+
|
|
81
|
+
input = Utils.convertToByteArray(input, inputType);
|
|
82
|
+
const output = encryptSM4(input, key, iv, mode.substring(0, 3), mode.endsWith("NoPadding"));
|
|
83
|
+
return outputType === "Hex" ? toHex(output) : Utils.byteArrayToUtf8(output);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export default SM4Encrypt;
|
|
@@ -22,7 +22,7 @@ class TripleDESDecrypt extends Operation {
|
|
|
22
22
|
|
|
23
23
|
this.name = "Triple DES Decrypt";
|
|
24
24
|
this.module = "Ciphers";
|
|
25
|
-
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.";
|
|
25
|
+
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.";
|
|
26
26
|
this.infoURL = "https://wikipedia.org/wiki/Triple_DES";
|
|
27
27
|
this.inputType = "string";
|
|
28
28
|
this.outputType = "string";
|
|
@@ -42,7 +42,7 @@ class TripleDESDecrypt extends Operation {
|
|
|
42
42
|
{
|
|
43
43
|
"name": "Mode",
|
|
44
44
|
"type": "option",
|
|
45
|
-
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
|
|
45
|
+
"value": ["CBC", "CFB", "OFB", "CTR", "ECB", "CBC/NoPadding", "ECB/NoPadding"]
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"name": "Input",
|
|
@@ -65,7 +65,8 @@ class TripleDESDecrypt extends Operation {
|
|
|
65
65
|
run(input, args) {
|
|
66
66
|
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
|
67
67
|
iv = Utils.convertToByteArray(args[1].string, args[1].option),
|
|
68
|
-
mode = args[2],
|
|
68
|
+
mode = args[2].substring(0, 3),
|
|
69
|
+
noPadding = args[2].endsWith("NoPadding"),
|
|
69
70
|
inputType = args[3],
|
|
70
71
|
outputType = args[4];
|
|
71
72
|
|
|
@@ -85,6 +86,14 @@ Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
|
|
85
86
|
input = Utils.convertToByteString(input, inputType);
|
|
86
87
|
|
|
87
88
|
const decipher = forge.cipher.createDecipher("3DES-" + mode, key);
|
|
89
|
+
|
|
90
|
+
/* Allow for a "no padding" mode */
|
|
91
|
+
if (noPadding) {
|
|
92
|
+
decipher.mode.unpad = function(output, options) {
|
|
93
|
+
return true;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
88
97
|
decipher.start({iv: iv});
|
|
89
98
|
decipher.update(forge.util.createBuffer(input));
|
|
90
99
|
const result = decipher.finish();
|
|
@@ -277,6 +277,8 @@ import SHA2 from "./SHA2.mjs";
|
|
|
277
277
|
import SHA3 from "./SHA3.mjs";
|
|
278
278
|
import SIGABA from "./SIGABA.mjs";
|
|
279
279
|
import SM3 from "./SM3.mjs";
|
|
280
|
+
import SM4Decrypt from "./SM4Decrypt.mjs";
|
|
281
|
+
import SM4Encrypt from "./SM4Encrypt.mjs";
|
|
280
282
|
import SQLBeautify from "./SQLBeautify.mjs";
|
|
281
283
|
import SQLMinify from "./SQLMinify.mjs";
|
|
282
284
|
import SSDEEP from "./SSDEEP.mjs";
|
|
@@ -647,6 +649,8 @@ export {
|
|
|
647
649
|
SHA3,
|
|
648
650
|
SIGABA,
|
|
649
651
|
SM3,
|
|
652
|
+
SM4Decrypt,
|
|
653
|
+
SM4Encrypt,
|
|
650
654
|
SQLBeautify,
|
|
651
655
|
SQLMinify,
|
|
652
656
|
SSDEEP,
|
package/src/node/index.mjs
CHANGED
|
@@ -278,6 +278,8 @@ import {
|
|
|
278
278
|
SHA3 as core_SHA3,
|
|
279
279
|
SIGABA as core_SIGABA,
|
|
280
280
|
SM3 as core_SM3,
|
|
281
|
+
SM4Decrypt as core_SM4Decrypt,
|
|
282
|
+
SM4Encrypt as core_SM4Encrypt,
|
|
281
283
|
SQLBeautify as core_SQLBeautify,
|
|
282
284
|
SQLMinify as core_SQLMinify,
|
|
283
285
|
SSDEEP as core_SSDEEP,
|
|
@@ -648,6 +650,8 @@ function generateChef() {
|
|
|
648
650
|
"SHA3": _wrap(core_SHA3),
|
|
649
651
|
"SIGABA": _wrap(core_SIGABA),
|
|
650
652
|
"SM3": _wrap(core_SM3),
|
|
653
|
+
"SM4Decrypt": _wrap(core_SM4Decrypt),
|
|
654
|
+
"SM4Encrypt": _wrap(core_SM4Encrypt),
|
|
651
655
|
"SQLBeautify": _wrap(core_SQLBeautify),
|
|
652
656
|
"SQLMinify": _wrap(core_SQLMinify),
|
|
653
657
|
"SSDEEP": _wrap(core_SSDEEP),
|
|
@@ -1035,6 +1039,8 @@ const SHA2 = chef.SHA2;
|
|
|
1035
1039
|
const SHA3 = chef.SHA3;
|
|
1036
1040
|
const SIGABA = chef.SIGABA;
|
|
1037
1041
|
const SM3 = chef.SM3;
|
|
1042
|
+
const SM4Decrypt = chef.SM4Decrypt;
|
|
1043
|
+
const SM4Encrypt = chef.SM4Encrypt;
|
|
1038
1044
|
const SQLBeautify = chef.SQLBeautify;
|
|
1039
1045
|
const SQLMinify = chef.SQLMinify;
|
|
1040
1046
|
const SSDEEP = chef.SSDEEP;
|
|
@@ -1407,6 +1413,8 @@ const operations = [
|
|
|
1407
1413
|
SHA3,
|
|
1408
1414
|
SIGABA,
|
|
1409
1415
|
SM3,
|
|
1416
|
+
SM4Decrypt,
|
|
1417
|
+
SM4Encrypt,
|
|
1410
1418
|
SQLBeautify,
|
|
1411
1419
|
SQLMinify,
|
|
1412
1420
|
SSDEEP,
|
|
@@ -1783,6 +1791,8 @@ export {
|
|
|
1783
1791
|
SHA3,
|
|
1784
1792
|
SIGABA,
|
|
1785
1793
|
SM3,
|
|
1794
|
+
SM4Decrypt,
|
|
1795
|
+
SM4Encrypt,
|
|
1786
1796
|
SQLBeautify,
|
|
1787
1797
|
SQLMinify,
|
|
1788
1798
|
SSDEEP,
|
|
@@ -119,7 +119,7 @@ TestRegister.addApiTests([
|
|
|
119
119
|
assert.strictEqual(result[0].module, "Ciphers");
|
|
120
120
|
assert.strictEqual(result[0].inputType, "string");
|
|
121
121
|
assert.strictEqual(result[0].outputType, "string");
|
|
122
|
-
assert.strictEqual(result[0].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.");
|
|
122
|
+
assert.strictEqual(result[0].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.");
|
|
123
123
|
assert.strictEqual(result[0].args.length, 5);
|
|
124
124
|
}),
|
|
125
125
|
|
|
@@ -75,6 +75,7 @@ import "./tests/SeqUtils.mjs";
|
|
|
75
75
|
import "./tests/SetDifference.mjs";
|
|
76
76
|
import "./tests/SetIntersection.mjs";
|
|
77
77
|
import "./tests/SetUnion.mjs";
|
|
78
|
+
import "./tests/SM4.mjs";
|
|
78
79
|
import "./tests/StrUtils.mjs";
|
|
79
80
|
import "./tests/SymmetricDifference.mjs";
|
|
80
81
|
import "./tests/TextEncodingBruteForce.mjs";
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SM4 crypto tests.
|
|
3
|
+
*
|
|
4
|
+
* Test data used from IETF draft-ribose-cfrg-sm4-09, see:
|
|
5
|
+
* https://tools.ietf.org/id/draft-ribose-cfrg-sm4-09.html
|
|
6
|
+
*
|
|
7
|
+
* @author swesven
|
|
8
|
+
* @copyright 2021
|
|
9
|
+
* @license Apache-2.0
|
|
10
|
+
*/
|
|
11
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
12
|
+
|
|
13
|
+
/* Cleartexts */
|
|
14
|
+
const TWO_BLOCK_PLAIN = "aa aa aa aa bb bb bb bb cc cc cc cc dd dd dd dd ee ee ee ee ff ff ff ff aa aa aa aa bb bb bb bb";
|
|
15
|
+
const FOUR_BLOCK_PLAIN = "aa aa aa aa aa aa aa aa bb bb bb bb bb bb bb bb cc cc cc cc cc cc cc cc dd dd dd dd dd dd dd dd ee ee ee ee ee ee ee ee ff ff ff ff ff ff ff ff aa aa aa aa aa aa aa aa bb bb bb bb bb bb bb bb";
|
|
16
|
+
/* Keys */
|
|
17
|
+
const KEY_1 = "01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10";
|
|
18
|
+
const KEY_2 = "fe dc ba 98 76 54 32 10 01 23 45 67 89 ab cd ef";
|
|
19
|
+
/* IV */
|
|
20
|
+
const IV = "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f";
|
|
21
|
+
/* Ciphertexts */
|
|
22
|
+
const ECB_1 = "5e c8 14 3d e5 09 cf f7 b5 17 9f 8f 47 4b 86 19 2f 1d 30 5a 7f b1 7d f9 85 f8 1c 84 82 19 23 04";
|
|
23
|
+
const ECB_2 = "c5 87 68 97 e4 a5 9b bb a7 2a 10 c8 38 72 24 5b 12 dd 90 bc 2d 20 06 92 b5 29 a4 15 5a c9 e6 00";
|
|
24
|
+
/* With PKCS#7 padding */
|
|
25
|
+
const ECB_1P ="5e c8 14 3d e5 09 cf f7 b5 17 9f 8f 47 4b 86 19 2f 1d 30 5a 7f b1 7d f9 85 f8 1c 84 82 19 23 04 00 2a 8a 4e fa 86 3c ca d0 24 ac 03 00 bb 40 d2";
|
|
26
|
+
const ECB_2P= "c5 87 68 97 e4 a5 9b bb a7 2a 10 c8 38 72 24 5b 12 dd 90 bc 2d 20 06 92 b5 29 a4 15 5a c9 e6 00 a2 51 49 20 93 f8 f6 42 89 b7 8d 6e 8a 28 b1 c6";
|
|
27
|
+
const CBC_1 = "78 eb b1 1c c4 0b 0a 48 31 2a ae b2 04 02 44 cb 4c b7 01 69 51 90 92 26 97 9b 0d 15 dc 6a 8f 6d";
|
|
28
|
+
const CBC_2 = "0d 3a 6d dc 2d 21 c6 98 85 72 15 58 7b 7b b5 9a 91 f2 c1 47 91 1a 41 44 66 5e 1f a1 d4 0b ae 38";
|
|
29
|
+
const OFB_1 = "ac 32 36 cb 86 1d d3 16 e6 41 3b 4e 3c 75 24 b7 1d 01 ac a2 48 7c a5 82 cb f5 46 3e 66 98 53 9b";
|
|
30
|
+
const OFB_2 = "5d cc cd 25 a8 4b a1 65 60 d7 f2 65 88 70 68 49 33 fa 16 bd 5c d9 c8 56 ca ca a1 e1 01 89 7a 97";
|
|
31
|
+
const CFB_1 = "ac 32 36 cb 86 1d d3 16 e6 41 3b 4e 3c 75 24 b7 69 d4 c5 4e d4 33 b9 a0 34 60 09 be b3 7b 2b 3f";
|
|
32
|
+
const CFB_2 = "5d cc cd 25 a8 4b a1 65 60 d7 f2 65 88 70 68 49 0d 9b 86 ff 20 c3 bf e1 15 ff a0 2c a6 19 2c c5";
|
|
33
|
+
const CTR_1 = "ac 32 36 cb 97 0c c2 07 91 36 4c 39 5a 13 42 d1 a3 cb c1 87 8c 6f 30 cd 07 4c ce 38 5c dd 70 c7 f2 34 bc 0e 24 c1 19 80 fd 12 86 31 0c e3 7b 92 6e 02 fc d0 fa a0 ba f3 8b 29 33 85 1d 82 45 14";
|
|
34
|
+
const CTR_2 = "5d cc cd 25 b9 5a b0 74 17 a0 85 12 ee 16 0e 2f 8f 66 15 21 cb ba b4 4c c8 71 38 44 5b c2 9e 5c 0a e0 29 72 05 d6 27 04 17 3b 21 23 9b 88 7f 6c 8c b5 b8 00 91 7a 24 88 28 4b de 9e 16 ea 29 06";
|
|
35
|
+
|
|
36
|
+
TestRegister.addTests([
|
|
37
|
+
{
|
|
38
|
+
name: "SM4 Encrypt: ECB 1, No padding",
|
|
39
|
+
input: TWO_BLOCK_PLAIN,
|
|
40
|
+
expectedOutput: ECB_1,
|
|
41
|
+
recipeConfig: [
|
|
42
|
+
{
|
|
43
|
+
"op": "SM4 Encrypt",
|
|
44
|
+
"args": [{string: KEY_1, option: "Hex"}, {string: "", option: "Hex"}, "ECB/NoPadding", "Hex", "Hex"]
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "SM4 Encrypt: ECB 2, No padding",
|
|
50
|
+
input: TWO_BLOCK_PLAIN,
|
|
51
|
+
expectedOutput: ECB_2,
|
|
52
|
+
recipeConfig: [
|
|
53
|
+
{
|
|
54
|
+
"op": "SM4 Encrypt",
|
|
55
|
+
"args": [{string: KEY_2, option: "Hex"}, {string: "", option: "Hex"}, "ECB/NoPadding", "Hex", "Hex"]
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "SM4 Encrypt: ECB 1, With padding",
|
|
61
|
+
input: TWO_BLOCK_PLAIN,
|
|
62
|
+
expectedOutput: ECB_1P,
|
|
63
|
+
recipeConfig: [
|
|
64
|
+
{
|
|
65
|
+
"op": "SM4 Encrypt",
|
|
66
|
+
"args": [{string: KEY_1, option: "Hex"}, {string: "", option: "Hex"}, "ECB", "Hex", "Hex"]
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "SM4 Encrypt: ECB 2, With padding",
|
|
72
|
+
input: TWO_BLOCK_PLAIN,
|
|
73
|
+
expectedOutput: ECB_2P,
|
|
74
|
+
recipeConfig: [
|
|
75
|
+
{
|
|
76
|
+
"op": "SM4 Encrypt",
|
|
77
|
+
"args": [{string: KEY_2, option: "Hex"}, {string: "", option: "Hex"}, "ECB", "Hex", "Hex"]
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "SM4 Encrypt: CBC 1",
|
|
83
|
+
input: TWO_BLOCK_PLAIN,
|
|
84
|
+
expectedOutput: CBC_1,
|
|
85
|
+
recipeConfig: [
|
|
86
|
+
{
|
|
87
|
+
"op": "SM4 Encrypt",
|
|
88
|
+
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CBC/NoPadding", "Hex", "Hex"]
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "SM4 Encrypt: CBC 2",
|
|
94
|
+
input: TWO_BLOCK_PLAIN,
|
|
95
|
+
expectedOutput: CBC_2,
|
|
96
|
+
recipeConfig: [
|
|
97
|
+
{
|
|
98
|
+
"op": "SM4 Encrypt",
|
|
99
|
+
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CBC/NoPadding", "Hex", "Hex"]
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: "SM4 Encrypt: OFB1",
|
|
105
|
+
input: TWO_BLOCK_PLAIN,
|
|
106
|
+
expectedOutput: OFB_1,
|
|
107
|
+
recipeConfig: [
|
|
108
|
+
{
|
|
109
|
+
"op": "SM4 Encrypt",
|
|
110
|
+
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "OFB", "Hex", "Hex"]
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: "SM4 Encrypt: OFB2",
|
|
116
|
+
input: TWO_BLOCK_PLAIN,
|
|
117
|
+
expectedOutput: OFB_2,
|
|
118
|
+
recipeConfig: [
|
|
119
|
+
{
|
|
120
|
+
"op": "SM4 Encrypt",
|
|
121
|
+
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "OFB", "Hex", "Hex"]
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "SM4 Encrypt: CFB1",
|
|
127
|
+
input: TWO_BLOCK_PLAIN,
|
|
128
|
+
expectedOutput: CFB_1,
|
|
129
|
+
recipeConfig: [
|
|
130
|
+
{
|
|
131
|
+
"op": "SM4 Encrypt",
|
|
132
|
+
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CFB", "Hex", "Hex"]
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: "SM4 Encrypt: CFB2",
|
|
138
|
+
input: TWO_BLOCK_PLAIN,
|
|
139
|
+
expectedOutput: CFB_2,
|
|
140
|
+
recipeConfig: [
|
|
141
|
+
{
|
|
142
|
+
"op": "SM4 Encrypt",
|
|
143
|
+
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CFB", "Hex", "Hex"]
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: "SM4 Encrypt: CTR1",
|
|
149
|
+
input: FOUR_BLOCK_PLAIN,
|
|
150
|
+
expectedOutput: CTR_1,
|
|
151
|
+
recipeConfig: [
|
|
152
|
+
{
|
|
153
|
+
"op": "SM4 Encrypt",
|
|
154
|
+
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CTR", "Hex", "Hex"]
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: "SM4 Encrypt: CTR1",
|
|
160
|
+
input: FOUR_BLOCK_PLAIN,
|
|
161
|
+
expectedOutput: CTR_2,
|
|
162
|
+
recipeConfig: [
|
|
163
|
+
{
|
|
164
|
+
"op": "SM4 Encrypt",
|
|
165
|
+
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CTR", "Hex", "Hex"]
|
|
166
|
+
}
|
|
167
|
+
]
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: "SM4 Decrypt: ECB 1",
|
|
171
|
+
input: ECB_1,
|
|
172
|
+
expectedOutput: TWO_BLOCK_PLAIN,
|
|
173
|
+
recipeConfig: [
|
|
174
|
+
{
|
|
175
|
+
"op": "SM4 Decrypt",
|
|
176
|
+
"args": [{string: KEY_1, option: "Hex"}, {string: "", option: "Hex"}, "ECB/NoPadding", "Hex", "Hex"]
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: "SM4 Decrypt: ECB 2",
|
|
182
|
+
input: ECB_2,
|
|
183
|
+
expectedOutput: TWO_BLOCK_PLAIN,
|
|
184
|
+
recipeConfig: [
|
|
185
|
+
{
|
|
186
|
+
"op": "SM4 Decrypt",
|
|
187
|
+
"args": [{string: KEY_2, option: "Hex"}, {string: "", option: "Hex"}, "ECB/NoPadding", "Hex", "Hex"]
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: "SM4 Decrypt: CBC 1",
|
|
193
|
+
input: CBC_1,
|
|
194
|
+
expectedOutput: TWO_BLOCK_PLAIN,
|
|
195
|
+
recipeConfig: [
|
|
196
|
+
{
|
|
197
|
+
"op": "SM4 Decrypt",
|
|
198
|
+
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CBC/NoPadding", "Hex", "Hex"]
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: "SM4 Decrypt: CBC 2",
|
|
204
|
+
input: CBC_2,
|
|
205
|
+
expectedOutput: TWO_BLOCK_PLAIN,
|
|
206
|
+
recipeConfig: [
|
|
207
|
+
{
|
|
208
|
+
"op": "SM4 Decrypt",
|
|
209
|
+
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CBC/NoPadding", "Hex", "Hex"]
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: "SM4 Decrypt: OFB1",
|
|
215
|
+
input: TWO_BLOCK_PLAIN,
|
|
216
|
+
expectedOutput: OFB_1,
|
|
217
|
+
recipeConfig: [
|
|
218
|
+
{
|
|
219
|
+
"op": "SM4 Decrypt",
|
|
220
|
+
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "OFB", "Hex", "Hex"]
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: "SM4 Decrypt: OFB2",
|
|
226
|
+
input: OFB_2,
|
|
227
|
+
expectedOutput: TWO_BLOCK_PLAIN,
|
|
228
|
+
recipeConfig: [
|
|
229
|
+
{
|
|
230
|
+
"op": "SM4 Decrypt",
|
|
231
|
+
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "OFB", "Hex", "Hex"]
|
|
232
|
+
}
|
|
233
|
+
]
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: "SM4 Decrypt: CFB1",
|
|
237
|
+
input: CFB_1,
|
|
238
|
+
expectedOutput: TWO_BLOCK_PLAIN,
|
|
239
|
+
recipeConfig: [
|
|
240
|
+
{
|
|
241
|
+
"op": "SM4 Decrypt",
|
|
242
|
+
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CFB", "Hex", "Hex"]
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
name: "SM4 Decrypt: CFB2",
|
|
248
|
+
input: CFB_2,
|
|
249
|
+
expectedOutput: TWO_BLOCK_PLAIN,
|
|
250
|
+
recipeConfig: [
|
|
251
|
+
{
|
|
252
|
+
"op": "SM4 Decrypt",
|
|
253
|
+
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CFB", "Hex", "Hex"]
|
|
254
|
+
}
|
|
255
|
+
]
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
name: "SM4 Decrypt: CTR1",
|
|
259
|
+
input: CTR_1,
|
|
260
|
+
expectedOutput: FOUR_BLOCK_PLAIN,
|
|
261
|
+
recipeConfig: [
|
|
262
|
+
{
|
|
263
|
+
"op": "SM4 Decrypt",
|
|
264
|
+
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CTR", "Hex", "Hex"]
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
name: "SM4 Decrypt: CTR1",
|
|
270
|
+
input: CTR_2,
|
|
271
|
+
expectedOutput: FOUR_BLOCK_PLAIN,
|
|
272
|
+
recipeConfig: [
|
|
273
|
+
{
|
|
274
|
+
"op": "SM4 Decrypt",
|
|
275
|
+
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CTR", "Hex", "Hex"]
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
},
|
|
279
|
+
]);
|