【问题标题】:Encrypting 30 bit Number into 6 Character Alphanumeric String将 30 位数字加密为 6 个字符的字母数字字符串
【发布时间】:2011-10-02 04:35:47
【问题描述】:

我正在寻找一种方法来加密/混淆 30 位数字。

结果将被分组为 3 组,并作为 6 个字符的字母数字以 base32 字母编码对用户可见,但用户应该无法在字母数字字符串中找到模式。例如,用户可以看到 3 个字符串:ASDFGH、LKJHGF、ZXCVBN,这些字符串可能映射到数字 1073741821、1073741822、1073741823。但是,这是他们应该无法轻易弄清楚的模式。

我研究了一些加密算法,例如 DES。这是一个糟糕而幼稚的尝试:

import struct
from Crypto.Cipher import DES
from .baseconv import base32_urlsafe

_KEY = '\x81\x98\xe1\x14<\xb3\xe8\x10'
_encryptor = DES.new(_KEY)

def encrypt_number(number):
    encrypted_i64 = struct.unpack(
        '!Q', _encryptor.encrypt(struct.pack('!Q', number))
    )[0]
    encrypted_i30 = encrypted_i64 >> 34
    return base32_urlsafe.encode(encrypted_i30)

但显然,如果需要,我将无法解密字符串,并且这种方法会丢失唯一性。还研究了使用 XOR,但这太可预测了,因为更多时候不是数字会处于连续序列中。

我从来没有像这样编码过。所以,我正在寻找一些加密算法/方法来研究和考虑。我正在使用 python,但欢迎使用其他语言的想法或示例。

【问题讨论】:

  • 你能多谈谈你的申请吗?如果我们知道您将如何使用这些代码、您要保护什么、它们需要安全多长时间、它们是否被重复使用等等,这可能会有所帮助。
  • 你需要倒车吗?如果没有,cryptographic hash function 可能是您最好的选择。
  • @Gareth Rees,我不希望外部用户弄清楚数字增长的速度。它们不应该被重复使用,它们需要在 90 天左右的时间内保持安全。我去了 user12398 建议的 skip32 解决方案。谢谢

标签: python security encryption cryptography bit-manipulation


【解决方案1】:

Format preserving encryption 在这里可能会有所帮助。

例如,Black 和 Rogaway 的论文“Ciphers with Arbitrary Finite Domains”中描述的循环行走方法似乎是一种潜在的解决方案。 例如。使用 32 位密码(Greg Rose 的 Skip32 就是一个例子)。 使用密码加密您的 30 位输入。如果结果是 30 位整数(即前 2 位 是 0) 那么你就完成了,否则继续用密码加密,直到你得到一个 30 位的结果。 相应地进行解密。

如果您不需要非常安全的解决方案,那么the Hasty Pudding cipher 可能是一个替代方案。它可以加密任意大小的输入。它被提交给了 AES 比赛,但并没有走得很远,因此没有得到很好的分析。我仍然希望它比在 stackoverflow 上提出的任何临时解决方案更合适。

【讨论】:

  • 谢谢,使用skip32是我采取的方法,我也考虑过GeePokey的方法,但决定我不想维护表。
【解决方案2】:

一种方法是创建一个包含 1B (2^30) 个唯一随机数的表 - 并使用您的 30 位数字作为该表的索引。

如果该表太大,您可以创建一个较小的表 - 比如说 32768 个条目并分别索引下半部分和上半部分。

为避免上半部分因连续值不发生变化,请在查找表之前将下半部分的加密值添加到上半部分。

加密

t = table of 32768 random values    
upper15 = input_value >> 15    
lower15 = input_value & 0x7FFF    
lowercoded = t[lower15]    
uppercoded = t[ ( lowercoded + upper15 ) % 32768 ]    
result = uppercoded << 15 + lowercoded

解密

upper15 = input_value >> 15    
lower15 = input_value & 0x7FFF    
lowereddecoded = t.index(lower15)    
tmp = t.index(upper15)    
tmp -= lower15    
if tmp< 0:   tmp += 32768    
upperdecoded = tmp    
result = upperdecoded << 15 + lowerdecoded

【讨论】:

    【解决方案3】:

    只需使用 Luby-Rackoff construction 滚动您自己的 30 位分组密码。

    对“F”框使用您想要的任何散列函数(例如,数据的murmurhash 的低 15 位加上一个密钥)并运行任意多轮,结果将是30 位数字的可逆伪随机排列。

    当然,它不会是“加密强”,但 30 位不可能。

    【讨论】:

    • 您忘记使轮函数依赖于轮数。如果你的所有回合都相同,那么结果很容易被滑动攻击攻击。请不要设计自己的密码。你能力不够。
    • @Accipitridae:感谢您的有用建议,但不要担心;我无意设计自己的密码。 (实际上,我怀疑这个网站上的任何人都有能力这样做。)但我当然希望每一轮的“密钥”数据都是不同的,因为我将其设想为维基百科描述中的 K_n 数据/图片。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    相关资源
    最近更新 更多