函数包装器如何交互?

时间:2018-05-05 23:12:01

标签: javascript node.js web

我正在研究这个项目:rsa-aes-client-server 我无法理解他们如何在文件夹" \ componnets \"中交互包装函数(aes-wrapper和rsa-wrapper)。和" \ static \ js \"?以及这些函数如何与index.js文件交互? 静态\ 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
    }

}());




部件\ 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');
});




1 个答案:

答案 0 :(得分:0)

static/js文件下的文件在客户端加载并公开一个全局变量,例如在rsa-wrapper中,此代码将添加将在{{rsaWrapper中使用的全局变量index.html。 1}}

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

componnets中的文件在服务器端使用,并加载require语句 客户端服务器与socket.io库进行交互,为双向客户端服务器交互提供了一种方式 通过socket.emit来发送消息和socket.on来收听消息