How do the functions-wrappers interact?

70
May 06, 2018, at 6:01 PM

I'm studying this project: rsa-aes-client-server and I can not understand how they interact wrapper-functions (aes-wrapper and rsa-wrapper) in folders "\componnets\" and "\static\js\"? and how these functions then interact with the index.js file? static\js\rsa-wrapper.js:

(function () { 
 
    'use strict'; 
 
    var crypto = window.crypto.subtle; 
    var rsaParams =  {name:"RSA-OAEP", hash: {name: "SHA-1"}}; 
 
    function importPublicKey(keyInPemFormat){ 
        return new Promise(function(resolve, reject){ 
            var key = converterWrapper.convertPemToBinary2(keyInPemFormat); 
            key = converterWrapper.base64StringToArrayBuffer(key); 
 
            crypto.importKey('spki', key, rsaParams, false, ["encrypt"]) 
                .then(function(cryptokey) { 
                    resolve(cryptokey); 
                }); 
        }); 
    } 
 
    function importPrivateKey(keyInPemFormat){ 
 
        var key = converterWrapper.convertPemToBinary2(keyInPemFormat); 
        key = converterWrapper.base64StringToArrayBuffer(key); 
 
        return new Promise(function(resolve, reject){ 
            crypto.importKey('pkcs8', key, rsaParams, false, ["decrypt"]) 
                .then(function(cryptokey) { 
                    resolve(cryptokey); 
                }); 
        }); 
    } 
 
    function publicEncrypt(keyInPemFormat, message) { 
        return new Promise(function(resolve, reject){ 
            importPublicKey(keyInPemFormat).then(function (key) { 
                crypto.encrypt(rsaParams, key, converterWrapper.str2abUtf8(message)) 
                    .then(function(encrypted){ 
                        resolve(converterWrapper.arrayBufferToBase64String(encrypted)); 
                    }); 
            }) 
        }); 
    } 
 
    function privateDecrypt(keyInPemFormat, encryptedBase64Message) { 
        return new Promise(function(resolve, reject){ 
            importPrivateKey(keyInPemFormat).then(function (key) { 
                crypto.decrypt(rsaParams, key, converterWrapper.base64StringToArrayBuffer(encryptedBase64Message)) 
                    .then(function(decrypted){ 
                        resolve(converterWrapper.arrayBufferToUtf8(decrypted)); 
                    }); 
            }); 
        }); 
    } 
 
    window.rsaWrapper = { 
        importPrivateKey: importPrivateKey, 
        importPublicKey: importPublicKey, 
        privateDecrypt: privateDecrypt, 
        publicEncrypt: publicEncrypt 
    } 
 
}());

components\rsa-wrapper.js

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 = fs.readFileSync(path.resolve(basePath, 'keys', 'server.public.pem')); 
    rsaWrapper.serverPrivate = fs.readFileSync(path.resolve(basePath, 'keys', 'server.private.pem')); 
    rsaWrapper.clientPub = fs.readFileSync(path.resolve(basePath, 'keys', 'client.public.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.serverExampleEncrypt = () => { 
    console.log('Server public encrypting'); 
 
    let enc = rsaWrapper.encrypt(rsaWrapper.serverPub, 'Server init hello'); 
    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.RSA_PKCS1_OAEP_PADDING 
    }, Buffer.from(message)); 
 
    return enc.toString('base64'); 
}; 
 
rsaWrapper.decrypt = (privateKey, message) => { 
    let enc = crypto.privateDecrypt({ 
        key: privateKey, 
        padding: crypto.RSA_PKCS1_OAEP_PADDING 
    }, Buffer.from(message, 'base64')); 
 
    return enc.toString(); 
}; 
 
module.exports = rsaWrapper;

index.js

const express = require('express'); 
const app = express(); 
const http = require('http').Server(app); 
const io = require('socket.io')(http); 
const rsaWrapper = require('./components/rsa-wrapper'); 
const aesWrapper = require('./components/aes-wrapper'); 
 
rsaWrapper.initLoadServerKeys(__dirname); 
rsaWrapper.serverExampleEncrypt(); 
 
// middleware for static processing 
app.use(express.static(__dirname + '/static')); 
 
// web socket connection event 
io.on('connection', function(socket){ 
 
    // Test sending to client dummy RSA message 
    let encrypted = rsaWrapper.encrypt(rsaWrapper.clientPub, 'Hello RSA message from client to server'); 
    socket.emit('rsa server encrypted message', encrypted); 
 
    // Test accepting dummy RSA message from client 
    socket.on('rsa client encrypted message', function (data) { 
        console.log('Server received RSA message from client'); 
        console.log('Encrypted message is', '\n', data); 
        console.log('Decrypted message', '\n', rsaWrapper.decrypt(rsaWrapper.serverPrivate, data)); 
    }); 
 
    // Test AES key sending 
    const aesKey = aesWrapper.generateKey(); 
    let encryptedAesKey = rsaWrapper.encrypt(rsaWrapper.clientPub, (aesKey.toString('base64'))); 
    socket.emit('send key from server to client', encryptedAesKey); 
 
    // Test accepting dummy AES key message 
    socket.on('aes client encrypted message', function (data) { 
        // console.log('Server received AES message from client', '\n', 'Encrypted message is', '\n', data); 
        console.log('Decrypted message', '\n', aesWrapper.decrypt(aesKey, data)); 
 
        // Test send client dummy AES message 
        let message = aesWrapper.createAesMessage(aesKey, 'Server AES message'); 
        socket.emit('aes server encrypted message', message); 
    }); 
}); 
 
http.listen(3000, function(){ 
    console.log('listening on *:3000'); 
});

Answer 1

The files under static/js file are loaded on the client side and expose a global variable for example in rsa-wrapper this code will add a global variable rsaWrapper that will be used in index.html

window.rsaWrapper = {
        importPrivateKey: importPrivateKey,
        importPublicKey: importPublicKey,
        privateDecrypt: privateDecrypt,
        publicEncrypt: publicEncrypt
    }

The files in componnets are used on the server side and loaded with require statement.
The client server interaction is made with socket.io library which provides a way for two way client server interactions.
The calls are done with socket.emit to send messages and socket.on to listen to messages

READ ALSO
shelljs “not found” error

shelljs “not found” error

I have belowsh file

61
How to change process.env variable using dotenv in client side based on staging or production?

How to change process.env variable using dotenv in client side based on staging or production?

I'm trying to change a socket domain based on whether the website is in development, staging, or production

73
Node.js API express web server MongoDB

Node.js API express web server MongoDB

I'm writing an Nodejs REST API using express web server and mongoDB as DB server

61
Node js Json add array

Node js Json add array

This is my query

139