diff --git a/pass/app/Crypto.js b/pass/app/Crypto.js
index bb56135fec7cf063b5d3906b12209e1e2faa5ac7..ad70e2fefbe2d8865704728f1087d96c3888130c 100644
--- a/pass/app/Crypto.js
+++ b/pass/app/Crypto.js
@@ -1,6 +1,9 @@
 const config = require("config");
 const { pki, random } = require("node-forge");
 const crypto = require("crypto");
+const BlindSignature = require("blind-signatures");
+var BigInteger = require("jsbn").BigInteger;
+const NodeRSA = require("node-rsa");
 
 class Crypto {
   #dayjs;
@@ -17,24 +20,21 @@ class Crypto {
   }
 
   private_key_get_current() {
-    let seed_date = this.#dayjs().format(this.#dayjs_format);
+    let seed_date = this.#dayjs();
     return this.#private_key_get(seed_date);
   }
 
   private_key_get_last() {
-    let seed_date = this.#dayjs()
-      .subtract(1, "month")
-      .format(this.#dayjs_format);
+    let seed_date = this.#dayjs().subtract(1, "month");
     return this.#private_key_get(seed_date);
   }
 
   async #private_key_get(seed_date) {
-    let private_key = {};
-
-    let cache_key = "private_keys" + seed_date;
+    let cache_key = "private_key_" + seed_date.format(this.#dayjs_format);
 
     // Check if the private key already exists in cache
     let cached_key = await this.#redis.get(cache_key);
+    let private_key = new NodeRSA();
     if (cached_key === null) {
       let seed = config.get("crypto.private_key.seed") + seed_date;
 
@@ -43,31 +43,45 @@ class Crypto {
       prng_instance.seedFileSync = () => seed;
 
       let keypair = pki.rsa.generateKeyPair({
-        bits: 4096,
+        bits: config.get("crypto.private_key.bit_length"),
         prng: prng_instance,
         workers: -1,
       });
+      let private_key_pem = pki
+        .privateKeyToPem(keypair.privateKey)
+        .trim()
+        .replace(/\r\n/g, "\n");
 
-      private_key = {
-        n: keypair.privateKey.n.toString(),
-        e: keypair.privateKey.e.toString(),
-        d: keypair.privateKey.d.toString(),
-        p: keypair.privateKey.p.toString(),
-        q: keypair.privateKey.q.toString(),
-        dmp1: keypair.privateKey.dP.toString(),
-        dmq1: keypair.privateKey.dQ.toString(),
-        coeff: keypair.privateKey.qInv.toString(),
-      };
+      private_key = private_key.importKey(
+        Buffer.from(private_key_pem, "utf8"),
+        "private"
+      );
 
       // Store the key in cache
-      await this.#redis.set(cache_key, JSON.stringify(private_key));
+      await this.#redis.set(cache_key, private_key.exportKey("pkcs8"));
     } else {
-      private_key = JSON.parse(await this.#redis.get(cache_key));
+      let private_key_data = await this.#redis.get(cache_key);
+      private_key = private_key.importKey(private_key_data, "pkcs8");
     }
-
     return private_key;
   }
 
+  async sign(encrypted_sales_receipts, order_date) {
+    let private_key = await this.#private_key_get(order_date);
+    console.log(private_key);
+    let signed_encrypted_sales_receipts = [];
+
+    for (let i = 0; i < encrypted_sales_receipts.length; i++) {
+      signed_encrypted_sales_receipts.push(
+        BlindSignature.sign({
+          blinded: new BigInteger(encrypted_sales_receipts[i]),
+          key: private_key,
+        }).toString()
+      );
+    }
+    return signed_encrypted_sales_receipts;
+  }
+
   /**
    * Creates an hmac hash for purchase data so we can check it later
    */
@@ -84,8 +98,8 @@ class Crypto {
       amount: parseInt(amount),
       unit_size: parseInt(unit_size),
       price_per_unit: parseFloat(price_per_unit),
-      public_key_n: public_key_n,
-      public_key_e: public_key_e,
+      public_key_n: new String(public_key_n),
+      public_key_e: new String(public_key_e),
     });
     let forge = require("node-forge");
     let hmac = forge.hmac.create();
@@ -111,8 +125,8 @@ class Crypto {
       amount: parseInt(amount),
       unit_size: parseInt(unit_size),
       price_per_unit: parseFloat(price_per_unit),
-      public_key_n: public_key_n,
-      public_key_e: public_key_e,
+      public_key_n: new String(public_key_n),
+      public_key_e: new String(public_key_e),
     });
     let forge = require("node-forge");
     let hmac = forge.hmac.create();
diff --git a/pass/app/Order.js b/pass/app/Order.js
index b6ac4ec33d18afc07e532953342b619d45ab8e2f..bbe4afd192cfce8684928525db16f043c9abdfe1 100644
--- a/pass/app/Order.js
+++ b/pass/app/Order.js
@@ -1,4 +1,5 @@
 const config = require("config");
+const Crypto = require("./Crypto");
 const dayjs = require("dayjs");
 
 class Order {
@@ -34,12 +35,14 @@ class Order {
   #unit_size;
   #price_per_unit;
   #encrypted_sales_receipts;
+  #signatures;
   #payment_completed;
   #payment_method_link; // Stores a link to an entry of the payment methods payment i.e. PayPal order id
 
   /**
    * Data populated by context
    */
+  #order_date;
   #create_mode;
   #redis_client;
 
@@ -48,14 +51,23 @@ class Order {
     amount,
     unit_size,
     price_per_unit,
-    encrypted_sales_receipts
+    encrypted_sales_receipts,
+    signatures
   ) {
-    this.#order_id = parseInt(order_id);
+    this.#order_id = new String(order_id);
+    this.#order_date = dayjs.unix(this.#order_id.substr(0, 10));
+
     this.#amount = parseInt(amount);
     this.#unit_size = parseInt(unit_size);
     this.#price_per_unit = parseFloat(price_per_unit);
     this.#encrypted_sales_receipts = encrypted_sales_receipts;
 
+    if (signatures) {
+      this.#signatures = signatures;
+    } else {
+      this.#signatures = [];
+    }
+
     this.#payment_completed = false;
     this.#create_mode = true;
 
@@ -81,6 +93,10 @@ class Order {
     return this.#payment_method_link;
   }
 
+  getSignatures() {
+    return this.#signatures;
+  }
+
   isPaymentComplete() {
     return this.#payment_completed;
   }
@@ -89,6 +105,16 @@ class Order {
     this.#payment_method_link = payment_method_link;
   }
 
+  async signOrder() {
+    let mgcrypto = new Crypto();
+
+    let signed_encrypted_sales_receipts = mgcrypto.sign(
+      this.#encrypted_sales_receipts,
+      this.#order_date
+    );
+    this.#signatures = await signed_encrypted_sales_receipts;
+  }
+
   static async LOAD_ORDER_FROM_ID(order_id) {
     return new Promise((resolve, reject) => {
       let Redis = require("ioredis");
@@ -106,7 +132,8 @@ class Order {
           order_data.amount,
           order_data.unit_size,
           order_data.price_per_unit,
-          order_data.encrypted_sales_receipts
+          JSON.parse(order_data.encrypted_sales_receipts),
+          JSON.parse(order_data.signatures)
         );
         if (order_data.payment_method_link) {
           loaded_order.setPaymentMethodLink(
@@ -140,7 +167,10 @@ class Order {
         amount: this.#amount,
         unit_size: this.#unit_size,
         price_per_unit: this.#price_per_unit,
-        encrypted_sales_receipts: this.#encrypted_sales_receipts,
+        encrypted_sales_receipts: JSON.stringify(
+          this.#encrypted_sales_receipts
+        ),
+        signatures: JSON.stringify(this.#signatures),
         payment_completed: this.#payment_completed,
         payment_method_link: JSON.stringify(this.#payment_method_link),
       })
diff --git a/pass/resources/js/checkout_paypal.js b/pass/resources/js/checkout_paypal.js
index cec426ddfdf36a51a8925a3e8a6a311242673f85..91b0eb51aa3256d3e32d4144b2d104466467c04c 100644
--- a/pass/resources/js/checkout_paypal.js
+++ b/pass/resources/js/checkout_paypal.js
@@ -70,7 +70,7 @@ function execute_payment_paypal(encrypted_sales_receipts) {
               .then((orderData) => {
                 let paymentEvent = new CustomEvent("payment-complete", {
                   detail: {
-                    orderData,
+                    signatures: orderData.signatures,
                   },
                   bubbles: true,
                   cancelable: true,
diff --git a/pass/routes/checkout/checkout.js b/pass/routes/checkout/checkout.js
index 229098e0f192d6de9bc9cac73740458e9d89ed47..1ae76b2602283696e88e5d131f1390e334325c37 100644
--- a/pass/routes/checkout/checkout.js
+++ b/pass/routes/checkout/checkout.js
@@ -35,8 +35,8 @@ router.get(
     let crypto = new Crypto();
     let private_key = await crypto.private_key_get_current();
     params.crypto = {
-      N: private_key.n,
-      E: private_key.e,
+      N: private_key.keyPair.n,
+      E: private_key.keyPair.e,
     };
 
     // Generate hmac hash of the payment data so we are able to verify them when the client submits them again
@@ -87,6 +87,7 @@ router.use(
           req.body.public_key_e
         )
       ) {
+        console.log("Invalid integrity");
         return Promise.reject("Integrity is not matching");
       }
       return true;
diff --git a/pass/routes/checkout/paypal.js b/pass/routes/checkout/paypal.js
index 1cde1f444f24be975081c6115c3cbbcc4faff0a6..79270524e32b1c24d9f8f5ae84507f4786bd8f76 100644
--- a/pass/routes/checkout/paypal.js
+++ b/pass/routes/checkout/paypal.js
@@ -18,6 +18,7 @@ router.post("/", async (req, res, next) => {
     req.body.price_per_unit,
     req.body.encrypted_sales_receipts
   );
+
   order
     .save()
     .then(() => {
@@ -38,10 +39,30 @@ router.post("/", async (req, res, next) => {
 // capture payment & store order information or fullfill order
 router.post("/capture", async (req, res) => {
   Order.LOAD_ORDER_FROM_ID(req.body.order_id).then((loaded_order) => {
-    let paypal_order_id = loaded_order.getPaymentMethodLink().id;
-    capturePayment(paypal_order_id).then((captureData) =>
-      res.json(captureData)
-    );
+    loaded_order
+      .signOrder()
+      .then(() => {
+        let paypal_order_id = loaded_order.getPaymentMethodLink().id;
+        capturePayment(paypal_order_id)
+          .then((captureData) => {
+            loaded_order
+              .save()
+              .then(() => {
+                captureData.signatures = loaded_order.getSignatures();
+                res.json(captureData);
+              })
+              .catch((error) => {
+                res.status(400).json({ errors: [{ msg: error }] });
+              });
+          })
+          .catch((error) => {
+            res.status(400).json({ errors: [{ msg: error }] });
+          });
+      })
+      .catch((error) => {
+        res.status(400).json({ errors: [{ msg: error }] });
+      });
+
     //res.json(captureData);
     // TODO: store payment information such as the transaction ID
   });