【问题标题】:Way to encrypt a single int加密单个 int 的方法
【发布时间】:2010-10-31 21:19:39
【问题描述】:

您如何以低成本双向加密 32 位 int,以使每个数字都映射到该空间中的某个其他 int,然后以难以预测的方式返回?

当然,也不需要在映射表中预先存储 42.9 亿个整数。

【问题讨论】:

  • 另见stackoverflow.com/questions/858476/… 不完全相同,但同样的推理也适用于解释为什么这不安全。
  • erickson:“不安全”取决于上下文。只要不可能进行选择明文攻击,“加密” 32 位整数就没有先验错误。

标签: algorithm language-agnostic encryption


【解决方案1】:

您需要的是 32 位分组密码。不幸的是,由于weaknesses of a short block size,大多数分组密码都是 64 位或更多位。如果您可以处理两倍于输入的加密 int,那么您可以只使用 Blowfish、TDES 或其他一些经过严格审查的 64 位分组密码。

如果您确实需要 32 位并且不介意降低的安全性,那么将像 Blowfish 之类的 Feistel 网络密码修剪到任何 2 的倍数且小于起始密码的块长度很容易。对于Blowfish,只需将您的输入数字平均分配在两个半块之间,然后将 F 函数的输出和 P 值缩减到目标块大小的 1/2。这一切都可以在像往常一样键入算法后完成。

【讨论】:

  • 这必须是整个线程中唯一理智的答案。恭喜! ;)
【解决方案2】:

显然,您需要某种随机密钥才能确保安全。在这种情况下:

int original = 42;
int key = give_me_a_random_int();

int encrypted = original ^ key;
int unencrypted = encrypted ^ key;

// now, unencrypted == original == 42

这只是一个简单的异或。再次异或将反转此过程。

另外,我应该注意,这仅对一次使用是安全的。它被称为One time pad。如果您对非随机数据使用相同的密钥两次,则攻击者可能会破译它。

【讨论】:

  • 如果纯文本中有任何模式或偏差,它们将在使用相同密钥加密的两条消息一起异或时显示出来。 (A ^ K) ^ (B ^ K) = A ^ B。
  • 另外 2^32 也不是蛮力的一个很大的键空间。
  • 当你多次使用同一个密钥并且攻击者可以进行已知的明文攻击时,异或算法是没有用的。已知 A 和 B = A ^ K 后,可以简单地得到 K = A ^ B。
  • @laalto:你不能暴力破解,但你只能在非随机数据上使用一次。
【解决方案3】:

使用 32 位分组密码,skip32 是我找到的唯一一个:http://www.qualcomm.com.au/PublicationsDocs/skip32.c

【讨论】:

  • 我同意。具有 32 位块的分组密码是可行的方法。
【解决方案4】:

一种方法是与一个秘密的 32 位数字进行异或。当你再次与这个秘密号码进行异或运算时,它将返回到原来的号码。这很快但不是很安全。如果需要一种安全的方法,我也有兴趣在这里查看其他方法。

【讨论】:

  • 假设密钥是秘密且随机的,这可能是安全的。
  • 这是非常不安全的:对两个输出数字进行异或运算将产生两个输入数字的异或,从而揭示很多有关来源的信息,并可能让攻击者找出秘密是什么。
  • 我的意思是一个数字。这是一次性使用的最安全的方法(请参阅一次性垫)。
【解决方案5】:

使用标准算法和随机填充(假设密文不需要与平面文本的长度相同)。

所以基本上,使用使用链接的标准算法并在其前面插入四个随机 32 位数字。这应该有助于掩饰 32 位消息中的任何规律性/冗余性。见鬼,如果你喜欢的话,最后也要垫。

基本上,你写得越少,你就越好。每个人都把这件事搞砸了。

【讨论】:

  • “每个人都搞砸了”对于发明自己的加密方案来说也是如此。
  • 我发明了初始化向量?摘自 Schneier 的 Applied Cryptography,第 194 页 一些消息有一个共同的标题:信头,或“发件人”行或其他。虽然区块重放仍然是不可能的,但这个相同的开始可能会给密码分析员提供有用的信息。通过加密随机数据作为第一个块来防止这种情况。这块随机数据称为初始化向量 (IV)。
  • 是的,但是您建议使用多个块,这是没有意义的,因为块密码的状态只有一个块长。当 OP 想要将 32 位 int 映射到另一个 32 位 int 时,它也并不真正适用。
  • 此外,大多数加密库将 IV 与数据分开处理,特别是因为某些区块链模式需要它。 :)
  • 嗯,假设他正在使用这样的库是不是有点冒昧?我提到填充会超过 1 对 1 的要求。你赢了单块的东西。我在那里做的数学不够彻底。不过,你不觉得在这里说我“发明了一个计划”有点不公平吗?
【解决方案6】:

您可以使用两种简单且可逆的操作来打乱整数值。可以使用异或运算,可以交换数字中的位。

如果您同时使用这两种方法,那么找出使用的方法就不是那么容易了。他们会在一定程度上互相保护。

【讨论】:

  • 您实际上是在建议提问者发明他们自己的分组密码。这似乎是一个糟糕的方法。
  • 它又快又简单,所以如果你只是想打乱值,它做得很好。当然,它对真正的加密没有多大作用,但无论如何,由于问题中给出的限制,这实际上是不可能的。
  • 当然是 - 使用分组密码,正如另一张海报所建议的那样。没有理由自己动手。
【解决方案7】:

如果您想要的只是普通用户不会注意到的真正简单的东西,那么请使用一系列 XOR 和移位运算符。

不使用数组来存储大约 40 亿个 INT 的问题在于,您需要一个函数来在 40 亿个 INT 的域中执行一对一的随机映射。您可以混合使用许多 XOR 和移位运算符来创建自己的,但它不会很难破解。即使有众所周知的一对一地图,它也会失败。如果没有盐,有人可以生成一个简单的彩虹表来破坏它。

盐以两种方式进行通信的问题在于您必须安全地进行通信。盐必须是秘密的,一旦你知道它们是什么,它们就毫无意义了。

如果您希望设置安全的通信渠道,请查看Off-the-Record Messaging Protocol version 2。它将为您提供一个示例,说明通信加密可以变得多么复杂。我建议您找到其他人已经创建和测试过的众所周知的东西。即使你确实使用了别人创造的东西,如果你使用不当,它也会失败。

【讨论】:

    【解决方案8】:

    获取 32 位输入,将其切成两个 16 位的一半 L 和 R,然后重复 以下步骤:计算 R 的伪随机函数,将此伪随机函数的结果异或到 L 并交换 L 和 R。这是一个Luby-Rackoff 构造。伪随机函数不需要是可逆的。因此,您可以例如采用分组密码,加密 16 位并将结果切割为 16 位。确保并非所有轮次都使用相同的伪随机函数(rsp.使用不同的轮次密钥)。

    【讨论】:

      【解决方案9】:

      看看:github.com/msootoodeh/integer-encoder 项目。它支持 32 位和 64 位整数。

      【讨论】:

        【解决方案10】:

        我曾经使用 XOR + ADD 和 64 位密钥。我还曾经每隔几分钟更改一次密钥,并尝试使用当前或以前的密钥进行解密。 (在我的域中,整数的安全时间不需要超过大约四分钟。)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-10
          • 2011-01-30
          • 1970-01-01
          • 2012-02-27
          • 2013-11-26
          • 1970-01-01
          相关资源
          最近更新 更多