From 20eaff7726ee3b2b3abc841cb8a6f705cb661497 Mon Sep 17 00:00:00 2001 From: Kajal Date: Sun, 22 Jul 2018 15:38:12 +0530 Subject: [PATCH] RSA Encryption between device and post-bridge --- server/.gitignore | 3 ++ server/app.js | 5 +++ server/crypto/init.js | 5 +++ server/crypto/rsa-wrapper.js | 63 ++++++++++++++++++++++++++++++++++++ server/package.json | 1 + server/subscribe_post.js | 13 ++++++-- server/virtualDevice.js | 16 +++++++-- 7 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 server/.gitignore create mode 100644 server/crypto/init.js create mode 100644 server/crypto/rsa-wrapper.js diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 0000000..5d0d3d4 --- /dev/null +++ b/server/.gitignore @@ -0,0 +1,3 @@ +crypto/keys +node_modules +npm-debug.log \ No newline at end of file diff --git a/server/app.js b/server/app.js index 6a721b5..1a7d612 100755 --- a/server/app.js +++ b/server/app.js @@ -10,6 +10,11 @@ var routDevices = require('./routes/devices'); const config = require("./config/database")//requiring database folder var subscrib = require('./subscribe_post'); +/** + * Create public and private keys of client and store them in file + */ +const rsaWrapper = require('./crypto/rsa-wrapper'); +rsaWrapper.generateIfRequired('server'); var app = express(); diff --git a/server/crypto/init.js b/server/crypto/init.js new file mode 100644 index 0000000..6250a5d --- /dev/null +++ b/server/crypto/init.js @@ -0,0 +1,5 @@ +const rsaWrapper = require('./rsa-wrapper'); +// generate opened and closed keys for browser and server +rsaWrapper.generate('server'); +rsaWrapper.generate('client'); +console.log('Keys generated …'); \ No newline at end of file diff --git a/server/crypto/rsa-wrapper.js b/server/crypto/rsa-wrapper.js new file mode 100644 index 0000000..9fe0ed7 --- /dev/null +++ b/server/crypto/rsa-wrapper.js @@ -0,0 +1,63 @@ +const path = require('path'); +const rsaWrapper = {}; +const fs = require('fs'); +const NodeRSA = require('node-rsa'); +const crypto = require('crypto'); + +// load keys from file +rsaWrapper.initLoadServerKeys = (basePath) => { + rsaWrapper.serverPub = rsaWrapper.loadKey(basePath, 'server', 'public'); + rsaWrapper.serverPrivate = rsaWrapper.loadKey(basePath, 'server', 'private'); + rsaWrapper.clientPub = rsaWrapper.loadKey(basePath, 'client', 'private'); +}; + +rsaWrapper.loadKey = (basePath, direction, type) => { + return fs.readFileSync(path.resolve(basePath, 'keys', `${direction}.${type}.pem`)); +}; + +rsaWrapper.generate = (direction) => { + let key = new NodeRSA(); + key.generateKeyPair(2048, 65537); + fs.writeFileSync(path.resolve(__dirname, 'keys', direction + '.private.pem'), key.exportKey('pkcs8-private-pem')); + fs.writeFileSync(path.resolve(__dirname, 'keys', direction + '.public.pem'), key.exportKey('pkcs8-public-pem')); + + return true; +}; + +rsaWrapper.generateIfRequired = (direction) => { + const exists = fs.existsSync(path.resolve(__dirname, 'keys', direction + '.private.pem')) + && fs.existsSync(path.resolve(__dirname, 'keys', direction + '.public.pem')); + + return exists || this.generate(direction); +} + +rsaWrapper.serverExampleEncrypt = () => { + console.log('Server public encrypting'); + + let enc = rsaWrapper.encrypt(rsaWrapper.serverPub, '{"sensor":"PIR","temperature":"44.77","humidity":"86.46","userid":"nakwarsi"}'); + console.log('Encrypted RSA string ', '\n', enc); + let dec = rsaWrapper.decrypt(rsaWrapper.serverPrivate, enc); + console.log('Decrypted RSA string ...'); + console.log(dec); +}; + +rsaWrapper.encrypt = (publicKey, message) => { + let enc = crypto.publicEncrypt({ + key: publicKey, + padding: crypto.constants.RSA_PKCS1_OAEP_PADDING + }, Buffer.from(message)); + + return enc.toString('base64'); +}; + +rsaWrapper.decrypt = (privateKey, message) => { + console.log('crypto.RSA_PKCS1_OAEP_PADDING', crypto.RSA_PKCS1_OAEP_PADDING); + let enc = crypto.privateDecrypt({ + key: privateKey, + padding: crypto.constants.RSA_PKCS1_OAEP_PADDING + }, Buffer.from(message, 'base64')); + + return enc.toString(); +}; + +module.exports = rsaWrapper; \ No newline at end of file diff --git a/server/package.json b/server/package.json index 3d42817..5e9f49f 100755 --- a/server/package.json +++ b/server/package.json @@ -15,6 +15,7 @@ "mongoose": "^5.1.6", "morgan": "~1.9.0", "mqtt": "^2.18.1", + "node-rsa": "^1.0.0", "request": "^2.87.0" } } diff --git a/server/subscribe_post.js b/server/subscribe_post.js index 50c75f4..1a73b5d 100644 --- a/server/subscribe_post.js +++ b/server/subscribe_post.js @@ -8,13 +8,20 @@ var client = mqtt.connect('mqtt://localhost:1883'); //var db_sensor = require('../mongoose/database'); let message; +const rsaWrapper = require('./crypto/rsa-wrapper'); +let serverPrivateKey; + var connectCallback = function () { console.log('mqtt broker connected') - client.subscribe('question2') + client.subscribe('question2'); + serverPrivateKey = rsaWrapper.loadKey('./crypto', 'server', 'private'); } -client.on('message', function (topic, msg) { - message = JSON.parse(msg); +client.on('message', function (topic, msg) { + const decrypted = rsaWrapper.decrypt(serverPrivateKey, msg.toString('utf8')); + console.log('DECRYPTED Message - ', decrypted); + + message = JSON.parse(decrypted); let DATA = { sensor: message.sensor, temperature: message.temperature, diff --git a/server/virtualDevice.js b/server/virtualDevice.js index b264f50..919326b 100644 --- a/server/virtualDevice.js +++ b/server/virtualDevice.js @@ -6,6 +6,15 @@ var interval_time = 1 var it = 5; var interval = -1; +/** + * Create public and private keys of client and store them in file + */ +const rsaWrapper = require('./crypto/rsa-wrapper'); +rsaWrapper.generateIfRequired('client'); + +const serverPublicKey = rsaWrapper.loadKey('./crypto', 'server', 'public'); +console.log('Sercver Public *******************', serverPublicKey); + function sentData() { @@ -15,8 +24,11 @@ function sentData() humidity: (Math.random() * 100).toFixed(2), userid: sen[Math.floor((Math.random() * 3).toFixed(2))] } - console.log('sent'); - client.publish('question2', JSON.stringify(data)) + + const encrypted = rsaWrapper.encrypt(serverPublicKey,JSON.stringify(data)); + console.log('\nDATA - ', encrypted); + + client.publish('question2', encrypted); it = interval_time }