我在后端使用 PyNacl 进行数字签名。我应该在前端使用哪个库?

Posted

技术标签:

【中文标题】我在后端使用 PyNacl 进行数字签名。我应该在前端使用哪个库?【英文标题】:I am using PyNacl at the backend for digital signatures. Which library should I use at frontend? 【发布时间】:2021-06-04 02:03:41 【问题描述】:

我创建了一个 API,用于在后端基于 PyNacl 验证数据。我为我的简单 Crypto API 接受长度为 64 的十六进制编码的发件人和收件人帐号,并基于 PyNacl 库验证签名。我想知道在我的前端使用什么 javascript 库,以便我使用基于 React 发送的数据与我的后端 API 保持一致。我查看了tweetnacl,但不确定它们是否具有相同的工作模式。你能给我一些关于我是否可以使用 tweetnacl 的信息,还是我必须创建一个 python 脚本,使用 PyNacl 生成签名密钥/验证密钥,并对消息进行签名?

谢谢。

【问题讨论】:

【参考方案1】:

更新!我们已成功在 TweetLua 和 PyNaCl 之间传递文件!编写 Lua 端代码的人有一个“差一”错误(愚蠢,但我们的大多数错误不是吗?)。一旦我们将正确的部件放在适当的位置,就很容易了。

我知道使用 Lua 而不是 JavaScript 并不能完美地解决这个问题,但我希望发现这个问题的人会得到一些相同的使用。归结为:是的,正如您所期望的那样,TweetNaCl 和 PyNaCl 是兼容的。

此过程中的重要元素:

TweetNaCl 在装箱和拆箱时将 MAC、Nonce、P_key 和 K_key 作为单独的参数。 PyNaCl 没有。捕获发送者的P_key,导入,做一个盒子,然后将剩余的密文作为一个单元传递。 PyNaCl 将为您提取 Nonce 和 MAC。

Lua 加密:

local function main(flag, files, keys)

   local pt = chunkpt(flag, files) # We broke large files down
    
   files.fout_size = companyfilesize(flag, pt)
   files.fout = assert(io.open(flag.outfile, "wb"))
   local current = files.fout:seek()
   files.fout:seek("set", files.fout_size - 1)
   files.fout:write("x")
   files.fout:seek("set", current)
    
   local err

   local ct = 
   local nonce = 
   local mac = 

   local root
   local nonceroot
   local macroot

   local n = #pt
   for i = n, 1, -1 do
      nonce[i] = nacl.randombytes(NONCE_LEN)
      if i == n then
         ct[i], err = nacl.box(pt[i], nonce[i], keys.p_rx, keys.k)
         if err ~= nil then error("boxing error") end

      else
         ct[i], err = nacl.box(pt[i] .. nonce[i + 1] .. mac[i + 1], nonce[i],
         keys.p_rx, keys.k)
         if err ~= nil then error("boxing error") end
      end
      mac[i] = ct[i]:sub(1, MAC_LEN)
      ct[i] = ct[i]:sub(MAC_LEN + 1, -1)
   end

   files.fout:seek("set", 0)

   local header = header_info
   files.fout:write(header)
   files.fout:write(keys.p_tx) 
   files.fout:write(nonce[1])
   files.fout:write(mac[1])
   files.fout:write(ct[1])    

   files.fin:close()
   files.fout:close()

   return 0
end

Python解密:

    def decrypt_box():
        with open("encrypted_file.companybox", 'rb') as f:
            header = f.read(16) # We use this for internal info
            senderPubKey = f.read(32) 
            cyphertext = f.read()
            f.close()

        # Import the secret key for use in the decryption
        imported_private_key = nacl.public.PrivateKey(BOB_SECRET_KEY)
        # Import the public key we just found in the file
        imported_public_key  = nacl.public.PublicKey(senderPubKey)

        # Make a box with the 2 keys
        plain_box = Box(imported_private_key, imported_public_key)

        # Pass the remaining text (that includes the Nonce and MAC) to decode
        plain = plain_box.decrypt(cyphertext)

        print(plain.decode('utf-8'))

之前的回复: 据我所知,不,TweetNaCl 和 PyNaCl 不兼容。我的小组正在尝试使用 c# TweetNaCl 加密文件并使用 python 解密,我总是得到一个通用的nacl.exceptions.CryptoError: An error occurred trying to decrypt the message。 如果您/其他人找到解决方案,我很乐意听到!

【讨论】:

我个人不认为这是一个答案。加密大多是标准化的,唯一的问题可能是这里的内容编码。最大的兼容性问题很可能是两个库是否支持相同的标准。 当然。这不是我满意的答案,因为我同意这应该可行,因为它们都基于 Libsodium。不过,到目前为止,这还没有发生。我的回答是基于实际经验,而不是理论,如果我们弄清楚了,我会发布更新。与此同时,我的目的只是为了节省别人的时间和精力。 如果您能在弄清楚后更新您的答案,我将非常高兴。遗憾的是,这种做法并不经常发生。我希望对内容编码的评论也能对您和您的团队有所帮助。这对我来说太常见了。 Python 3+ 使用 utf-8 作为标准文本文件编码,我不确定 C# 但我可以看到建议使用 UTF-16 的问题。类似的问题可能与字节编码有关。

以上是关于我在后端使用 PyNacl 进行数字签名。我应该在前端使用哪个库?的主要内容,如果未能解决你的问题,请参考以下文章

我应该在后端(Rails API)还是前端(React/Redux)上查询和过滤

支付宝支付数字商品

如何在后端动态定义 Autolayout

JSON 仅在后端和前端之间

如何在后端应用程序等前端 js 应用程序中使用变量替换?

使用数字进行用户管理(Fabric iOS)