javascript - 函数包装器如何交互?
问题描述
我正在研究这个项目:rsa-aes-client-server ,我无法理解它们如何与文件夹“\componnets\”和“\static\js\”中的包装函数(aes-wrapper 和 rsa-wrapper)交互?以及这些函数如何与 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');
});
解决方案
file 下的static/js
文件在客户端加载并公开一个全局变量,例如在rsa-wrapper
此代码中将添加一个全局变量rsaWrapper
,该变量将用于index.html
window.rsaWrapper = {
importPrivateKey: importPrivateKey,
importPublicKey: importPublicKey,
privateDecrypt: privateDecrypt,
publicEncrypt: publicEncrypt
}
中的文件在componnets
服务器端使用并加载了require
语句。
客户端服务器交互是使用socket.io库进行的,该库为两种客户端服务器交互提供了一种方式。
呼叫完成socket.emit
以发送消息和socket.on
收听消息
推荐阅读
- javascript - 禁用执行 POST 请求的能力
- python - Python Pandas - 累积列
- docker - 如何让 nginx 日志显示在 prometheus 中?
- ios - ARKit World Maps – 如何使用自定义 UTI 文件类型保存/访问?
- vba - 允许在一个打开的工作簿中使用 UDF,但使其在另一个工作簿中不可见/不可用/不可访问
- python - 僵尸 zeppelin-spark 进程的来源是什么?
- linux - 如果不在同一目录中,则无法运行配置文件
- c - 从 word 文档中删除段落标签只会导致 microsoft word 损坏
- javascript - 用javascript代码块替换html块,在“文档”错误上执行“写入”失败
- python - Python。多处理池。如何获得所有结果