python - 在 tweet-nacl (javascript) 中加密并在 python 中解密
问题描述
这个问题与这里现有的问题相反: Encrypt in python 3.7 and decode in NODEJS 12。
我更愿意在 python 上使用与tweet-nacl完全相同的东西,但该项目说它很旧,不推荐使用https://github.com/warner/python-tweetnacl。他们推荐的替代品是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。在这里。您可以在此处找到使用 PyNaCl 的公钥加密的文档,并在此处找到一般的 PyNaCl的文档。
在以下示例中,明文使用 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 的 Libsodium 的包装器(此处和此处),但 Libsodium 本身是 NaCl 的端口(此处),JavaScript 的 TweetNacl.js 也是如此(此处)。
所以最终,TweetNaCl 和 PyNaCl 都基于 NaCl,这是 Bernstein等人实现的原始库。, 秒。here,因此是兼容的(可能除了一些小的语法差异)。
推荐阅读
- angular - “typeof Component”类型的参数不能分配给“ComponentType”类型的参数
- c# - 如何修复数据类型中的“详细信息页面”错误
- c# - 如何正确处理临时文件?
- php - 如何创建可在多个页面上访问的一种自定义帖子类型 (-slug)?
- php - 如何从 url 获取大量参数但没有 (&)?
- sql-server - QT tableview QODBCResult::exec: 无法执行语句:
- javascript - Sequelize-cli:在播种文件之前预运行另一个种子文件?
- amazon-web-services - 如何使用 Terraform 自动化一次性 AWS 资源?
- stm32 - 尝试使用 STM32L452RE 微控制器从 MAX144 外部 ADC 获取数据但没有成功:(
- android - 获取 FileProvider 使用的路径名称