我计划将一堆记录存储在一个文件中,然后用 libsodium 对每个记录进行签名。 .但是,我希望我的程序的 future 版本能够检查当前版本所做的签名,反之亦然。
对于当前版本的钠,签名是使用 Ed25519 算法进行的。我想默认原语可以在新版本的钠中改变(否则 libsodium 不会公开一种选择特定的方法,我认为)。
我是不是该...
crypto_sign
)crypto_sign_ed25519
)sodium_library_version_major()
的值在文件中(在专用的“钠版本”字段或一般的“文件格式修订版”字段中)并在当前运行的版本较低时退出 crypto_sign_primitive()
crypto_sign_bytes()
和 friend 们……还是我应该完全做其他事情?
我的程序将用 C 编写。
最佳答案
让我们首先确定可能出现的问题集,然后尝试解决它。我们有一些数据(记录)和签名。签名可以用不同的算法计算。程序可以进化和改变它的行为,libsodium 也可以(独立地)进化和改变它的行为。在签名生成方面,我们有:
crypto_sign()
,它使用一些默认算法来生成签名(在编写时只是调用 crypto_sign_ed25519()
)crypto_sign_ed25519()
,它根据特定的 ed25519
生成签名算法 我假设对于一个给定相同输入数据和相同 key 的特定算法,我们总是会得到相同的结果,因为它是数学问题,任何与此规则的偏差都会使库完全无法使用。
让我们来看看两个主要选项:
crypto_sign_ed25519()
一直并且从不改变这一点。不错的选择,因为它很简单而且只要 crypto_sign_ed25519()
存在于 libsodium 中并且其输出稳定,您无需担心稳定的固定大小签名和零管理开销。当然,将来有人会发现这个算法的一些可怕的问题,如果你不准备改变算法,这对你来说可能意味着可怕的问题。 crypto_sign()
.有了这个我们突然有很多问题,因为算法可以改变,所以你必须在签名的同时存储一些元数据,这就引出了一组问题:对于第二种方法,我们在提到的函数中有什么?
sodium_library_version_major()
是一个告诉我们库 API 版本的函数。它与支持/默认算法的更改没有直接关系,因此它对我们的问题几乎没有用。 crypto_sign_primitive()
是一个函数,它返回一个字符串来标识 crypto_sign()
中使用的算法。 .这是我们需要的完美匹配,因为据说它的输出会在算法发生变化的时候发生变化。 crypto_sign_bytes()
是一个返回由 crypto_sign()
生成的签名大小的函数以字节为单位。这对于确定签名所需的存储量很有用,但如果算法发生变化,它很容易保持不变,因此它不是我们需要显式存储的元数据。 现在我们知道要存储什么,接下来是处理存储数据的问题。您需要获取算法名称并使用它来调用匹配验证函数。不幸的是,据我所知,libsodium 本身并没有提供任何简单的方法来获得给定算法名称的正确函数(如 openssl 中的
EVP_get_cipherbyname()
或 EVP_get_digestbyname()
),因此您需要自己制作一个(当然应该未知名称失败)。如果您必须自己制作一个,那么存储一些数字标识符而不是库中的名称会更容易(尽管代码更多)。现在让我们回到文件级与记录级。为了解决这个问题,还有另外两个问题要问——您是否可以在任何给定时间为旧记录生成新签名(技术上可行,政策允许),您是否需要将新记录附加到旧文件中?
如果您无法为旧记录生成新签名,或者您需要追加新记录并且不希望签名重新生成的性能损失,那么您没有太多选择,您需要:
如果您可以生成新签名,或者特别是如果您不需要附加新记录,那么当您将算法存储在特殊的文件级字段中时,如果签名算法发生变化,您可以使用更简单的文件级方法, 在保存文件时重新生成所有签名(或在附加新记录时使用旧签名,这也是一个兼容性策略问题)。
其他选择?那么,
crypto_sign()
有什么特别之处? ?它的行为不受您的控制,libsodium 开发人员为您选择算法(毫无疑问他们选择了好的算法),但是如果您的文件结构中有任何版本信息(不是特定于签名的,我的意思是)没有什么可以阻止您做出您自己的特定选择,将一种算法用于一种文件版本,另一种算法用于另一种(当然,需要时使用转换代码)。同样,这也是基于您可以生成新签名并且策略允许的假设。这让我们回到了最初的两个选择,问题是与仅使用
crypto_sign_ed25519()
相比,这样做是否值得麻烦。 .这主要取决于您的程序生命周期,我可能会说(仅作为意见)如果不到 5 年,那么只使用一种特定的算法会更容易。如果它很容易超过 10 年,那么不,你真的需要能够经受住算法(甚至可能是整个加密库)的变化。
关于c - 如何正确使用 libsodium 以使其在版本之间兼容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37526846/