【问题标题】:Javascript public/private key encryptionJavascript 公钥/私钥加密
【发布时间】:2018-02-27 10:20:48
【问题描述】:

我想用javascript生成一个公钥/私钥对,用公钥加密消息,用私钥解密消息。

我更喜欢原生浏览器支持而不是外部库。 如何在 JavaScript 中做到这一点?

现代浏览器实现window.crypto.subtle.generateKey。 我可以使用它来生成 ECDSA 私钥/公钥来签名/验证消息,这很有效。但是我找不到如何使用它来生成 pub/private 密钥来加密/解密的方法。如果我尝试使用推荐的 AES-GCM 算法的 generateKey,它只会生成一个 cryptoKey,它可能用于加密和解密。但我更喜欢获得一个密钥对(publib/private 密钥),而不仅仅是一个密钥。有什么建议吗?

此表列出了当前支持的方法,但似乎没有一个绿色算法是我需要的: https://diafygi.github.io/webcrypto-examples/

【问题讨论】:

  • 既然 JavaScript 在用户的浏览器中运行,这怎么可能是安全的呢?任何调试器都可以很容易地隔离您的私钥,从而否定加密的全部目的。我的建议是将私钥端托管在 php 或 asp 或其他服务器端进程中,因此用户无法浏览代码。
  • 当然可以,但我的问题是绿色标记的算法都没有生成私钥。
  • @Jim 有时目标是将密钥与服务器隔离(即为用户提供端到端加密)。它的实用性是一罐蠕虫。
  • AES 不是 symmetric-key algorithm 吗?我只希望它只产生一个私有密钥。您需要使用不同的算法来生成公共/私有对。

标签: javascript encryption


【解决方案1】:

由于 ProtonMail 的努力,现在浏览器中有一个开源的对称密钥加密实现:https://openpgpjs.org/

这已经过多次安全审核,并且是 protonmail.com 的基础,因此它有相当好的记录和维护人员。他们还对重要的安全浏览器模型进行了很好的总结。

【讨论】:

    【解决方案2】:

    幸运的是,您指向的页面显示支持 ECDH(包括 ECDH 密钥对生成)。这可以用来实现ECIES encryption scheme。然后,您可以将原始位用作原始 AES 密钥并将其用于 AES-GCM 模式。

    安全性当然取决于系统,而众所周知,Java Script 加密很难做到正确。这种方案只应 TLS 之外使用,即使那样也只能极其小心。

    【讨论】:

    • 我不确定我是否理解正确。我需要一个将发送给其他人以加密消息的公钥,我需要一个将保留在浏览器中的私钥,以便稍后解密消息。根据您的建议,我将拥有 ECDH 密钥对(公钥和私钥),但它们只能用于派生密钥。那么,如果我从中派生出一个 AES 密钥,它是否可以用作公钥进行加密,并且我将能够使用我的私有 (ECDH) 密钥进行解密?
    • 不,无论您做什么,您都需要对方的可信公钥来向他发送加密消息。如果您没有,那么任何人都可以创建自己的密钥对并要求您进行加密。或者,如果您向他们发送私钥,那么任何人都可以使用它来解密消息。收到公钥后,您可以创建一个临时密钥对来派生一个秘密 AES 密钥。然后,您将加密的消息和(不受信任的)公钥发送给其他人。该其他人还派生 AES 密钥并解密消息。 “Once”中的所有内容都只是对 IES 的描述
    【解决方案3】:

    mdn example

    const encode = (e => e.encode.bind(e))(new TextEncoder)
    
    let { publicKey: pub, privateKey: key } = await crypto.subtle.generateKey({ name: 'ECDH', namedCurve: 'P-521' }, true, ['deriveKey']) // generate key pairs
    
    // get server ecdh public key
    let jwk = await fetch('/others public key').then(res=>res.json())
    let spub = await crypto.subtle.importKey('jwk', jwk, { name: 'ECDH', namedCurve: 'P-521' }, false, [])
    
    // use spub and key derive a ase key
    let gcm = crypto.subtle.deriveKey({ name: 'ECDH', namedCurve: 'P-521', public: spub }, key, { name: 'AES-GCM', length: 256 }, true, ["encrypt", "decrypt"])
    
    // now use gcm to encrypt or decrypt
    let text = crypto.subtle.encrypt({ name: 'AES', length: 256 }, gcm, encode('hello world'))
    
    // same on the server

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 2013-04-06
      • 2013-05-07
      相关资源
      最近更新 更多