代码之家  ›  专栏  ›  技术社区  ›  Dimitrios Desyllas

在单独线程上生成电子运行加密Diffie-Hellman密钥

  •  1
  • Dimitrios Desyllas  · 技术社区  · 7 年前

    const crypto = require('crypto');
    
    /**
     * Generate the keys and the diffie hellman key agreement object.
     * @param {Integer} p The prime for Diffie Hellman Key Generation
     * @param {Integer} g The generator for Diffie Hellman Key Exchange
     */
    async function createSelfKey(p, g, callback) {
      let returnVal = null;
      if (p && g) {
        returnVal = { dh: await crypto.createDiffieHellman(p, g) };
      } else {
        returnVal = { dh: await crypto.createDiffieHellman(2048) };
      }
      returnVal.keys = await returnVal.dh.generateKeys();
      return callback(returnVal);
    };
    

    但是密钥生成是一个计算量稍大的过程,因此它使我的应用程序冻结。一个使用示例是当我尝试实现此方法时 generateCreatorKeys 从以下功能:

    function ChatRoomStatus() {
      /**
       * @var {Object}
       */
      const chatrooms = {};
    
      // Some other logic
        /**
       * This Method fetched the creator of the Chatroom and executes a callback on it.
       * @param {String} chatroom The chatroom to fetch the creator
       * @param {Function} callback The callback of the chatroom.
       */
      this.processCreator = (chatroom, callback) => {
        const index = _.findIndex(chatrooms[chatroom].friends, (friend) => friend.creator);
        return callback(chatrooms[chatroom].friends[index], index , chatrooms[chatroom] );
      };
    
    
      /**
       * Generate keys for the Chatroom Creator:
       * @param {String} chatroom The chatroom to fetch the creator
       * @param {Function} callback The callback of the chatroom.
       */
      this.generateCreatorKeys =  (chatroom, callback) => {
        return this.processCreator(chatroom, (friend, index, chatroom) => {
           return createSelfKey(null, null, (cryptoValues) => {
            friend.encryption = cryptoValues;
            return callback(friend, index, chatroom);
           });
        });
      };
    };
    

    const { xml, jid } = require('@xmpp/client');
    
    /**
     * Handling the message Exchange for group Key agreement 
     * @param {Function} sendMessageCallback 
     * @param {ChatRoomStatus} ChatroomWithParticipants 
     */
    function GroupKeyAgreement(sendMessageCallback, ChatroomWithParticipants) {
      const self = this;
      /**
       * Send the Owner participant Keys into the Chatroom
       */
      self.sendSelfKeys = (chatroomJid, chatroomName) => {
        ChatroomWithParticipants.generateCreatorKeys(chatroomName, (creator) => {
          const message = xml('message', { to: jid(chatroomJid).bare().toString()+"/"+creator.nick });
          const extention = xml('x', { xmlns: 'http://pcmagas.tk/gkePlusp#intiator_key' });
          extention.append(xml('p', {}, creator.encryption.dh.getPrime().toString('hex')));
          extention.append(xml('g', {}, creator.encryption.dh.getGenerator().toString('hex')));
          extention.append(xml('pubKey', {}, creator.encryption.keys.toString('hex')));
          message.append(extention);
          sendMessageCallback(message);
        });
      };
    };
    
    module.exports = GroupKeyAgreement;
    

    你知道我如何“运行”这个函数吗 createSelfKey 并行/分离线程,并通过回调服务其内容?此外,上面的代码在Electron的主进程上运行,因此冻结它会导致整个应用程序暂停一段时间。

    2 回复  |  直到 7 年前
        1
  •  2
  •   ccnokes    7 年前

    我想看看 https://electronjs.org/docs/tutorial/multithreading .

    Electron基本上拥有从DOM和node.js到更多的内容,因此您有一些选择。一般来说,它们是:

    1. 看起来node.js worker_线程(仅渲染器进程?)现在也可以在Electron中使用。这可能也行,但从未亲自使用过。
    2. 您始终可以创建另一个渲染器进程,并将其用作单独的“线程”,并通过IPC与之通信。工作完成后,你只需关闭它。您可以通过创建一个新的隐藏Browser窗口来实现这一点。

    因为您在主进程中运行此代码,并且假设无法将其移出,所以(据我所知)您唯一的选择是#3。如果你可以添加一个库,electron remote( https://github.com/electron-userland/electron-remote#the-renderer-taskpool )有一些很酷的功能,可以让你在后台启动一个(或多个)渲染器进程,得到结果作为承诺,然后为你关闭它们。

        2
  •  0
  •   Dimitrios Desyllas    7 年前

    我试图解决您的问题的最佳解决方案是以下基于 answer

    const crypto = require('crypto');
    const spawn = require('threads').spawn;
    
    /**
     * Generate the keys and the diffie hellman key agreement object.
     * @param {Integer} p The prime for Diffie Hellman Key Generation
     * @param {Integer} g The generator for Diffie Hellman Key Exchange
     * @param {Function} callback The callback in order to provide the keys and the diffie-hellman Object.
     */
    const createSelfKey = (p, g, callback) => {
    
      const thread = spawn(function(input, done) {
        const cryptot = require('crypto');
        console.log(input);
        const pVal = input.p;
        const gVal = input.g;
        let dh = null;
    
        if (pVal && gVal) {
          dh = cryptot.createDiffieHellman(pVal, gVal);
        } else {
          dh = cryptot.createDiffieHellman(2048);
        }
    
        const pubKey = dh.generateKeys();
        const signaturePubKey = dh.generateKeys();
        done({ prime: dh.getPrime().toString('hex'), generator: dh.getGenerator().toString('hex'), pubKey, signaturePubKey});
      });
    
      return thread.send({p,g}).on('message', (response) => {
        callback( crypto.createDiffieHellman(response.prime, response.generator), response.pubKey, response.signaturePubKey);
        thread.kill();
      }).on('error', (err)=>{
        console.error(err);
      }).on('exit', function() {
        console.log('Worker has been terminated.');
      });
    };
    

    如您所见,使用 threads