我计划将一堆记录存储在一个文件中,然后用libsodium对每条记录进行签名。但是,我希望我的程序的未来版本能够检查当前版本的签名,理想情况下反之亦然。
对于当前版本的Sodium,使用Ed25519算法进行签名。我想可以在Sodium的新版本中更改默认原语(否则libsodium不会公开选择特定版本的方法,我认为)。
我应该......
crypto_sign
)crypto_sign_ed25519
)sodium_library_version_major()
的值存储在文件中(在专用的钠版本'字段或一般'文件格式版本'字段中)并在当前运行的版本较低时退出crypto_sign_primitive()
crypto_sign_bytes()
和朋友......或者我应该完全做其他事情吗?
我的程序将以C语言编写。
答案 0 :(得分:2)
让我们首先确定可能存在的问题,然后尝试解决。我们有一些数据(记录)和签名。可以使用不同的算法来计算签名。该程序可以发展和改变其行为,libsodium也可以(独立地)发展和改变其行为。在签名生成方面,我们有:
crypto_sign()
,它使用一些默认算法来生成签名(在写作时只调用crypto_sign_ed25519()
)crypto_sign_ed25519()
,根据特定的ed25519
算法生成签名我假设对于一个特定的算法,给定相同的输入数据和相同的密钥,我们总会得到相同的结果,因为它的数学和任何偏离此规则将使库完全无法使用。
让我们来看看两个主要选项:
crypto_sign_ed25519()
并且永远不会更改此内容。这个选项并不是那么糟糕,因为它很简单,只要在libsodium中存在crypto_sign_ed25519()
并且在输出中是稳定的,你就不用担心稳定的固定大小签名和零管理开销。当然,将来有人可以通过这种算法发现一些可怕的问题,如果你不准备改变算法,这对你来说可能意味着可怕的问题。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年,那么不,你真的需要能够存活算法(甚至可能是整个加密库)的变化。
答案 1 :(得分:2)
只需使用高级API。
高级API中的函数不会使用不同的算法,如果没有碰撞库的主要版本。
在libsodium 1.x.y中可以预期的唯一重大变化是删除已弃用/未记录的函数(在使用--enable-minimal
开关编译的当前版本中甚至不存在)。其他一切都将保持向后兼容。
新的算法可能会在没有高级包装器的1.x.y版本中引入,并且将通过libsodium 2中的新高级API进行稳定和公开。
因此,请不要打扰crypto_sign_ed25519()
。只需使用crypto_sign()
。