在 tweet-nacl (javascript) 中加密并在 python 中解密

Encrypt in tweet-nacl (javascript) and decrypt in python

这个问题与这里现有的问题相反: .

我更愿意在 python 上使用 tweet-nacl 的完全等价物,但那个项目说它是旧的并且不推荐 https://github.com/warner/python-tweetnacl . Their recommended replacement is https://github.com/pyca/pynacl :但是那个是 libsodium 的接口而不是 tweet-nacl 并且没有关于如何实现解密的明确文档。

这里是JS加密:

    let msgArr = naclutil.decodeUTF8(jprint(msg))
    let nonce = nacl.randomBytes(nacl.box.nonceLength)
    let keyPair = this.genKeyPair()
    let encrypted = nacl.box(
      msgArr,
      nonce,
      naclutil.decodeBase64(pubKey),
      naclutil.decodeBase64(keyPair.privkey)
    )
    let nonce64 = naclutil.encodeBase64(nonce)
    let encrypted64 = naclutil.encodeBase64(encrypted)

(工作)tweet-nacl javascript 解密代码是:

  const decryptedMessage = nacl.box.open(
    naclutil.decodeBase64(payload.encrypted.encrypted),
    naclutil.decodeBase64(payload.encrypted.nonce),
    naclutil.decodeBase64(payload.encrypted.ephemPubKey),
    naclutil.decodeBase64(privKey)
  )
  const decodedMessage = naclutil.encodeUTF8(decryptedMessage)

我的问题是 pynacl 他们没有显示任何使用 ephemPubKey 进行解密的示例。我能找到的例子如下:

        import binascii
        from nacl.encoding import HexEncoder
        from nacl.exceptions import CryptoError
        from nacl.secret import Aead, SecretBox
        benc=       binascii.unhexlify(encrypted)
        bnonce =    binascii.unhexlify(nonce)
        box = SecretBox(privKey, encoder=HexEncoder)
        decrypted = box.decrypt(benc, bnonce, encoder=HexEncoder),

有没有人能够将 tweet-nacl Javascript 生成的加密成功解密为 python?

SecretBox 因此您发布的 PyNaCl 示例用于 对称 加密,s。 here. You can find the documentation for public key encryption with PyNaCl here and for PyNaCl in general here.

在下面的示例中,明文使用 TweetNaCl.js 加密并使用 PyNaCl 解密。

JavaScript 端 - 使用 TweetNaCl.js:
加密
var secretKey_js  = nacl.util.decodeBase64("FJGsHP0dMkDNkpAkT4hZrcbv27L8XNO8ymhLxpPpDkE=");
var publicKey_py = nacl.util.decodeBase64("0EyrzGW6qn0EGEV0Cx2Z7tQeln6FdwZVINz0FezlvTM=");
var nonce = nacl.randomBytes(24)
var msgStr = "The quick brown fox jumps over the lazy dog";
var message = nacl.util.decodeUTF8(msgStr);
var box_js = nacl.box(message, nonce, publicKey_py, secretKey_js)
console.log(nacl.util.encodeBase64(nonce))  // 2e8WuEr0+5nc14VBxQrOl4ob6guOTySr
console.log(nacl.util.encodeBase64(box_js)) // eJ8sO0mFNaaWLeXVcNNpw0PurwfINp/BlnErSzOnxXJ5zqu3wLrW4fHIa4kIAxFkuMVJaf0AR4pYon0=

代码和你的代码基本一样,只是没有生成密钥,而是导入密钥。

Python 方 - 用 PyNaCl 解密:
import base64
from nacl.public import PrivateKey, PublicKey, Box
from nacl.encoding import Base64Encoder

secretKeyB64_py  = "XVdFnozXd+7xm6MVazPemgSq6un+fGpDvwgxo9UbsdM=";
publicKeyB64_js = "ixxgLis2RzqMWys76HuoH7TwrwBbXoDrwl3jGsRysRI=";

secretKey_py = PrivateKey(secretKeyB64_py, encoder=Base64Encoder)
publicKey_js = PublicKey(publicKeyB64_js, encoder=Base64Encoder)

nonce = base64.b64decode("2e8WuEr0+5nc14VBxQrOl4ob6guOTySr");
box_js = base64.b64decode("eJ8sO0mFNaaWLeXVcNNpw0PurwfINp/BlnErSzOnxXJ5zqu3wLrW4fHIa4kIAxFkuMVJaf0AR4pYon0=");

box_py = Box(secretKey_py, publicKey_js)
data = box_py.decrypt(nonce + box_js)

print(data) # b'The quick brown fox jumps over the lazy dog'

在上面的示例中,密钥已被导入。如果需要生成密钥对,则使用 PyNaCl 完成,如下所示:

from nacl.public import PrivateKey

secretKeyNew = PrivateKey.generate()
publicKeyNew = secretKeyNew.public_key

关于兼容性:
TweetNaCl.js 和 PyNaCl 兼容。正如您所描述的,尽管 PyNaCl 是 Python (s. here and here), but Libsodium itself is a port of NaCl (s. here), as is TweetNacl.js for JavaScript (here) 的 Libsodium 的包装。
所以最终,TweetNaCl 和 PyNaCl 都是基于 NaCl,这是 Bernstein et al., s. 实现的原始库。 here,因此是兼容的(除了一些细微的句法差异)。