任何加密方案都会安全地允许我重复加密同一个整数,每次都会添加不同的随机材料吗?这似乎是那种可能让我陷入热水的操作。
我想阻止在我的网络应用程序中抓取项目,但仍然有持久的项目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
答案 0 :(得分:2)
如果您的加密是安全的,那么随机填充使得破解既不容易也不难。对于这个简短的消息,一个块长,无论是一切都被妥协或什么都没有。即使使用流密码,您仍然需要密钥才能获得更多信息;良好的加密点是你不需要额外的随机性。如果可能的话,显然应该避免在开头长至少一个块的零填充或其他已知消息,但这不是问题。这是纯粹的噪音,一旦有人发现,他们就会跳过前面并从那里开始破解。
现在,在流密码中,您可以在开头添加所有随机性,后面的字节仍然与相同的密钥相同,不要忘记。这实际上只对块密码做了任何事情,否则你必须将随机位xor转换为实际值才能获得任何用途。
但是,您可能最好使用MAC作为填充:使用适当的加密,加密的mac不会提供任何信息,但它看起来是半随机的,您可以使用它来验证没有错误或解密过程中的恶意攻击。你喜欢的任何哈希函数都可以创建MAC,即使是简单的CRC-32,也不会在加密后给出任何东西。
(由于相关性,密码学家可能会找到一种方法来削减一两次,如果他们事先知道它们是如何相关的话,会有大量的明文,但这仍然远远超出实用性。)
正如你之前所说,你可以安全地在每条信息前面加入未加密的盐;只要盐被正确地混合到密钥中,特别是如果您可以在解密之前将其混合到扩展密钥计划中,则只有在实施中断或密钥泄露时,盐才能破坏加密值。具有大量位的现代哈希算法非常擅长,但即使混合到常规输入键也将始终具有与单独密钥相同的安全性。