问题描述
我需要找到函数 F 和 F_Verification 使得:
- F(Input1,RandomSeed1) = Output1
- F(Input1,RandomSeed2) = Output2
- F_Verification (Output1,Output2) = TRUE
加密要求:
- 给定 Output1 和 Output2,您一定无法找到输入。
- F 可能是一个满射函数,产生相同的输出 ~1/Billion~ 次。最好在它是 surjective 的频率上有一些灵活性。
- F_Verification 可能会再次产生误报~1/Billion~ 次,但具有一定的灵活性
额外的细节
任何关于起点的建议将不胜感激。 谢谢。
解决方法
通常,您将很难找到执行此操作的函数,因为大多数加密函数的输出被设计为与随机无法区分。因此,您不太可能找到一个函数,它既可以基于随机种子产生两个相同的输出,又可以让您在不知道种子的情况下恢复有关输入值的任何信息。
但是,您可以使用一些结构。如果两个输出可以是完全相同的输出,那么您可以跳过随机种子并让 F 成为安全哈希函数,如 SHA-256 或 BLAKE2b。然后验证是相等比较。这是设计散列函数的理想情况,除非您知道需要不同的行为,否则我建议这样做。
如果你需要有两个不同的输出,你可以把F设为:
F(input,seed) = SHA-256(input) || HMAC-SHA-256(seed,input)
这仍然表明您的对象是相同的,但它在不同的种子上提供了不同的输出。验证是前32个字节的相等比较。
除此之外,您还会看到验证费用不菲的情况。您可以使用 RSA-PSS 对对象进行签名,即使输入(您将对其进行散列)相同,您在签名中使用的盐也会使两个签名不同。但就加密功能而言,RSA 验证并不是超级便宜,尽管有更糟糕的选择。
几乎所有其他操作都涉及了解种子以进行比较,而您尚未提供该选项作为选项。如果是,您可以使用 256 位种子并将 F 设置为:
F(input,seed) = AES-Key-Wrap(seed,SHA-256(input))