1

任何加密方案都可以安全地允许我重复加密相同的整数,每次都添加不同的随机材料吗?这似乎是一种可能让我陷入困境的手术。

我想防止在我的 Web 应用程序中抓取项目,但仍然具有持久的项目 ID/URL,因此内容链接不会随着时间的推移而过期。我对此的安全要求并不高,但我宁愿不要做一些完全愚蠢的事情,这显然会泄露秘密。

// performed on each ID before transmitting item search results to the client
public int64 encryptWithRandomPadding(int32 id) {
    int32 randomPadding = getNextRandomInt32();
    return encrypt(((int64)randomPadding << 32) + id), SECRET);
}

// performed on an encrypted/padded ID for which the client requests details
public int32 decryptAndRemoveRandomPadding(int64 idToDecrypt) {
    int64 idWithPadding = decrypt(idToDecrypt, SECRET);
    return (int32)idWithPadding;
}

static readonly string SECRET = "thesecret";

生成的 ID/URL 是永久性的,加密的 ID 是稀疏填充的(uint32.Max 中小于 1 是唯一的,我可以添加另一个常量填充以减少存在猜测的可能性),并且客户端可以运行相同的搜索和每次使用不同的代表 ID 得到相同的结果。我认为它符合我的要求,除非存在明显的密码问题。

例子:

 encrypt(rndA + item1)   -> tokenA
 encrypt(rndB + item1)   -> tokenB
 encrypt(rndC + item2)   -> tokenC
 encrypt(rndD + item175) -> tokenD

在这里,无法确定 tokenA 和 tokenB 都指向相同的项目;这可以防止蜘蛛删除重复的搜索结果而不检索它们(同时检索会增加使用量表)。此外,item2 可能不存在。

知道重新运行搜索将返回具有相同秘密的相同 int32 填充的多种方式,我可以使用任何流行的加密算法安全地做到这一点吗?谢谢,加密专家!

注意:这是一个没有像我希望的那样解决的问题的后续行动:Encrypt integer with a secret and shared salt

4

1 回答 1

2

如果您的加密是安全的,那么随机填充会使破解变得既不简单也不困难。对于这么短、一个块长的消息,要么一切都被破坏,要么什么都没有。即使使用流密码,您仍然需要密钥才能获得进一步的信息;良好加密的关键在于您不需要额外的随机性。如果可能的话,显然要避免零填充或其他至少在开始时至少一个块长的已知消息,但这不是这里的问题。这是纯粹的噪音,一旦有人发现,他们就会跳过并从那里开始破解。

现在,在流密码中,您可以在开头添加所有随机性,并且后面的字节仍然使用相同的密钥,不要忘记这一点。这实际上只对分组密码有任何作用,否则您必须将随机位异或到实际值中才能使用它。

但是,您最好使用 MAC 作为填充:通过适当的加密,加密后的 mac 不会泄露任何信息,但它看起来是半随机的,您可以使用它来验证期间没有错误或恶意攻击解密。您喜欢的任何散列函数都可以创建 MAC,即使是简单的 CRC-32,也不会在加密后泄露任何内容。

(由于相关性,密码学家可能会找到一种方法来减少一两次,如果他们事先知道它们是如何相关的,他们会发现大量的明文,但这仍然远远超出了实用性。)

正如您之前所问的,您可以安全地在每条消息前添加未加密的盐;如果实现被破坏或密钥被泄露,盐只能破坏加密的值,只要盐被正确地混合到密钥中,特别是如果您可以在解密之前将其混合到扩展的密钥计划中。具有大量位的现代散列算法非常擅长这一点,但即使混合到常规输入密钥中,也始终具有与单独的密钥相同的安全性。

于 2012-07-29T04:52:51.330 回答