在 C# 中使用尽可能小的数字签名对消息进行签名

Sign a message with as small as possible digital signature in c#

我工作的公司想创建某种注册流程,最后用户必须输入密钥才能激活他的产品。

我已经搜索并找到了一些解释如何生成密钥的来源。其中一位 (How to generate and validate a software license key?) 建议获取一些数据(如注册数据,结合硬件信息),并将其与数据散列的私钥加密连接起来,并在所有这些基础上计算 base32 编码.

所以在程序中输入密钥时,会解码base32,计算数据的has,用public密钥验证密钥中的签名是否有效(这样我们就可以确定钥匙来自我们公司)。

我发现了关于 Bouncy castle 的信息,但我没有在其中看到任何 schnorr 实现(事实上,我没有在 c# 中找到很多 if 的实现)。我制作小签名的所有努力都失败了(我设法创建的最小签名是 56 字节)。

所以假设数据 + 签名是 64 字节。我的 base 32 字符串将是 64 * 8 / 5,即 103 chars.combined 带有额外的 - 用于定界,并使其更具可读性,我们得到一些不可读且不能由 [=28= 指示的东西](如果需要)。

那我错过了什么? 如果我需要制作一个 32 个字符的密钥,那么我需要 20 个字节的数据 + 散列。

我该怎么做?

任何使用 .net 密码学或 Bouncy Castle(缺少任何 c# 文档和示例)的示例都会有所帮助。

我了解到 ed25519 是基于 schnorr 的,至少从我读到的内容来看是这样。 找到 ed25519 的实现并不难。我发现 libsodium.net 使用 libsodium(一个 c++ 库),它包装了 c++ 库。

还有一个叫做 NaCl.Net (salt.net) 的东西,它是 libsodium.net 的完全托管版本。 NaCl.Net 的文档丢失,并且没有像我预期的那样工作(API 与 libsodium.Net 中的不同)。

总之,用libsodium.Net我设法加密了一条小消息,得到了一条加密的小消息。

例如,对于一条 4 字节的消息,我得到了一条 20 字节的加密消息。 对于 8 字节的消息,我得到 24 字节的消息。

额外的16个字节一点也不差(密钥大小是32个字节,这意味着256位,在这个算法中应该是好的)

算法详情

密钥交换:Curve25519 加密:XSalsa20 流密码 身份验证:Poly1305 MAC

签署消息会创建更大的签名消息,但我不需要它。 我要计算数据的哈希值,并从中生成密钥(使用加密)。

收到密钥后,将对其进行解密,然后将给定的哈希值与在计算机上计算的哈希值进行比较。