Переглянути джерело

Tidied up SM4 ops and NoPadding options for AES, DES and TripleDES

n1474335 3 роки тому
батько
коміт
8117926ca3

+ 2 - 2
src/core/config/Categories.json

@@ -83,12 +83,12 @@
             "RC2 Decrypt",
             "RC4",
             "RC4 Drop",
+            "SM4 Encrypt",
+            "SM4 Decrypt",
             "ROT13",
             "ROT47",
             "XOR",
             "XOR Brute Force",
-            "SM4 Encrypt",
-            "SM4 Decrypt",
             "Vigenère Encode",
             "Vigenère Decode",
             "To Morse Code",

+ 7 - 5
src/core/lib/SM4.mjs

@@ -38,7 +38,8 @@ const Sbox = [
     0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
     0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
     0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
-    0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48];
+    0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
+];
 
 /** "Fixed parameter CK" used in key expansion */
 const CK = [
@@ -170,7 +171,7 @@ export function encryptSM4(message, key, iv, mode="ECB", noPadding=false) {
     if (mode === "ECB" || mode === "CBC") {
         if (noPadding) {
             if (nPadding !== 16)
-                throw new OperationError("No padding requested in "+mode+" mode but input is not a 16-byte multiple.");
+                throw new OperationError(`No padding requested in ${mode} mode but input is not a 16-byte multiple.`);
             nPadding = 0;
         } else
             padByte = nPadding;
@@ -255,10 +256,11 @@ export function decryptSM4(cipherText, key, iv, mode="ECB", ignorePadding=false)
         /* Init decryption key */
         roundKey = roundKey.reverse();
         if ((originalLength & 0xF) !== 0 && !ignorePadding)
-            throw new OperationError("With ECB or CBC modes, the input must be divisible into 16 byte blocks. ("+(cipherText.length & 0xF)+" bytes extra)");
-    } else /* Pad dummy bytes for other modes, chop them off at the end */
+            throw new OperationError(`With ECB or CBC modes, the input must be divisible into 16 byte blocks. (${cipherText.length & 0xF} bytes extra)`);
+    } else { /* Pad dummy bytes for other modes, chop them off at the end */
         while ((cipherText.length & 0xF) !== 0)
             cipherText.push(0);
+    }
 
     const clearText = [];
     switch (mode) {
@@ -310,7 +312,7 @@ export function decryptSM4(cipherText, key, iv, mode="ECB", ignorePadding=false)
             }
             break;
         default:
-            throw new OperationError("Invalid block cipher mode: "+mode);
+            throw new OperationError(`Invalid block cipher mode: ${mode}`);
     }
     /* Check PKCS#7 padding */
     if (mode === "ECB" || mode === "CBC") {

+ 4 - 1
src/core/operations/AESDecrypt.mjs

@@ -113,6 +113,7 @@ class AESDecrypt extends Operation {
         const key = Utils.convertToByteString(args[0].string, args[0].option),
             iv = Utils.convertToByteString(args[1].string, args[1].option),
             mode = args[2].substring(0, 3),
+            noPadding = args[2].endsWith("NoPadding"),
             inputType = args[3],
             outputType = args[4],
             gcmTag = Utils.convertToByteString(args[5].string, args[5].option),
@@ -130,12 +131,14 @@ The following algorithms will be used based on the size of the key:
         input = Utils.convertToByteString(input, inputType);
 
         const decipher = forge.cipher.createDecipher("AES-" + mode, key);
+
         /* Allow for a "no padding" mode */
-        if (args[2].endsWith("NoPadding")) {
+        if (noPadding) {
             decipher.mode.unpad = function(output, options) {
                 return true;
             };
         }
+
         decipher.start({
             iv: iv.length === 0 ? "" : iv,
             tag: mode === "GCM" ? gcmTag : undefined,

+ 5 - 2
src/core/operations/DESDecrypt.mjs

@@ -66,6 +66,7 @@ class DESDecrypt extends Operation {
         const key = Utils.convertToByteString(args[0].string, args[0].option),
             iv = Utils.convertToByteArray(args[1].string, args[1].option),
             mode = args[2].substring(0, 3),
+            noPadding = args[2].endsWith("NoPadding"),
             [,,, inputType, outputType] = args;
 
         if (key.length !== 8) {
@@ -84,12 +85,14 @@ Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
         input = Utils.convertToByteString(input, inputType);
 
         const decipher = forge.cipher.createDecipher("DES-" + mode, key);
-         /* Allow for a "no padding" mode */
-        if (args[2].endsWith("NoPadding")) {
+
+        /* Allow for a "no padding" mode */
+        if (noPadding) {
             decipher.mode.unpad = function(output, options) {
                 return true;
             };
         }
+
         decipher.start({iv: iv});
         decipher.update(forge.util.createBuffer(input));
         const result = decipher.finish();

+ 1 - 1
src/core/operations/SM4Decrypt.mjs

@@ -24,7 +24,7 @@ class SM4Decrypt extends Operation {
         this.name = "SM4 Decrypt";
         this.module = "Ciphers";
         this.description = "SM4 is a 128-bit block cipher, currently established as a national standard (GB/T 32907-2016) of China.";
-        this.infoURL = "https://en.wikipedia.org/wiki/SM4_(cipher)";
+        this.infoURL = "https://wikipedia.org/wiki/SM4_(cipher)";
         this.inputType = "string";
         this.outputType = "string";
         this.args = [

+ 1 - 1
src/core/operations/SM4Encrypt.mjs

@@ -24,7 +24,7 @@ class SM4Encrypt extends Operation {
         this.name = "SM4 Encrypt";
         this.module = "Ciphers";
         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.";
-        this.infoURL = "https://en.wikipedia.org/wiki/SM4_(cipher)";
+        this.infoURL = "https://wikipedia.org/wiki/SM4_(cipher)";
         this.inputType = "string";
         this.outputType = "string";
         this.args = [

+ 5 - 2
src/core/operations/TripleDESDecrypt.mjs

@@ -22,7 +22,7 @@ class TripleDESDecrypt extends Operation {
 
         this.name = "Triple DES Decrypt";
         this.module = "Ciphers";
-        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.";
+        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.";
         this.infoURL = "https://wikipedia.org/wiki/Triple_DES";
         this.inputType = "string";
         this.outputType = "string";
@@ -66,6 +66,7 @@ class TripleDESDecrypt extends Operation {
         const key = Utils.convertToByteString(args[0].string, args[0].option),
             iv = Utils.convertToByteArray(args[1].string, args[1].option),
             mode = args[2].substring(0, 3),
+            noPadding = args[2].endsWith("NoPadding"),
             inputType = args[3],
             outputType = args[4];
 
@@ -85,12 +86,14 @@ Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
         input = Utils.convertToByteString(input, inputType);
 
         const decipher = forge.cipher.createDecipher("3DES-" + mode, key);
+
         /* Allow for a "no padding" mode */
-        if (args[2].endsWith("NoPadding")) {
+        if (noPadding) {
             decipher.mode.unpad = function(output, options) {
                 return true;
             };
         }
+
         decipher.start({iv: iv});
         decipher.update(forge.util.createBuffer(input));
         const result = decipher.finish();

+ 1 - 1
tests/node/tests/nodeApi.mjs

@@ -119,7 +119,7 @@ TestRegister.addApiTests([
         assert.strictEqual(result[0].module, "Ciphers");
         assert.strictEqual(result[0].inputType, "string");
         assert.strictEqual(result[0].outputType, "string");
-        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.");
+        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.");
         assert.strictEqual(result[0].args.length, 5);
     }),