فهرست منبع

Implement RSA generation and signing of messages

GCHQ 77703 6 سال پیش
والد
کامیت
f81ca3ba60
3فایلهای تغییر یافته به همراه144 افزوده شده و 0 حذف شده
  1. 2 0
      src/core/config/Categories.json
  2. 82 0
      src/core/operations/GenerateRSAKeyPair.mjs
  3. 60 0
      src/core/operations/RSASign.mjs

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

@@ -89,6 +89,8 @@
             "Derive EVP key",
             "Bcrypt",
             "Scrypt",
+            "Generate RSA Key Pair",
+            "RSA Sign",
             "Pseudo-Random Number Generator"
         ]
     },

+ 82 - 0
src/core/operations/GenerateRSAKeyPair.mjs

@@ -0,0 +1,82 @@
+/**
+ * @author gchq77703 []
+ * @copyright Crown Copyright 2018
+ ` * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import forge from "node-forge/dist/forge.min.js";
+
+/**
+ * Generate RSA Key Pair operation
+ */
+class GenerateRSAKeyPair extends Operation {
+
+    /**
+     * GenerateRSAKeyPair constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Generate RSA Key Pair";
+        this.module = "Ciphers";
+        this.description = "Generate an RSA key pair with a given number of bits";
+        this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                name: "RSA Key Length",
+                type: "option",
+                value: [
+                    "1024",
+                    "2048",
+                    "4096"
+                ]
+            },
+            {
+                name: "Output Format",
+                type: "option",
+                value: [
+                    "PEM",
+                    "JSON",
+                    "DER"
+                ]
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    async run(input, args) {
+        const [keyLength, outputFormat] = args
+
+        return new Promise((resolve, reject) => {
+            forge.pki.rsa.generateKeyPair({ bits: Number(keyLength), workers: 2 }, (err, keypair) => {
+                if (err) return reject(err)
+
+                let result;
+
+                switch(outputFormat) {
+                    case "PEM":
+                        result = forge.pki.publicKeyToPem(keypair.publicKey) + "\n" + forge.pki.privateKeyToPem(keypair.privateKey);
+                        break;
+                    case "JSON":
+                        result = JSON.stringify(keypair);
+                        break;
+                    case "DER":
+                        result = forge.asn1.toDer(forge.pki.privateKeyToAsn1(keypair.privateKey)).getBytes();
+                        break;
+                };
+
+                resolve(result);
+            })
+        })
+    }
+
+}
+
+export default GenerateRSAKeyPair;

+ 60 - 0
src/core/operations/RSASign.mjs

@@ -0,0 +1,60 @@
+/**
+ * @author gchq77703 []
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import forge from "node-forge/dist/forge.min.js";
+
+/**
+ * RSA Sign operation
+ */
+class RSASign extends Operation {
+
+    /**
+     * RSASign constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "RSA Sign";
+        this.module = "Ciphers";
+        this.description = "Sign a plaintext message with a PEM encoded RSA key.";
+        this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
+        this.inputType = "string";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                name: "RSA Private Key (PEM)",
+                type: "text",
+                value: "-----BEGIN RSA PRIVATE KEY-----"
+            },
+            {
+                name: "Password",
+                type: "text",
+                value: ""
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const [key, password] = args;
+
+        const privateKey = forge.pki.decryptRsaPrivateKey(key, password);
+
+        const md = forge.md.sha1.create();
+        md.update(input, 'utf8');
+        const signature = privateKey.sign(md);
+
+        return signature.split('').map(char => char.charCodeAt());
+    }
+
+}
+
+export default RSASign;