gpt4 book ai didi

python - 将整数(最多 2^48)安全加密为最短的 URL 安全字符串

转载 作者:太空宇宙 更新时间:2023-11-04 05:13:20 25 4
gpt4 key购买 nike

在我的 Django 应用程序中,我有分层的 URL 结构:

webpage.com/property/PK/sub-property/PK/ 等...

我不想公开主键并创建漏洞。因此我是将所有 PK 加密为所有模板和 URL 中的字符串。这是由精彩的图书馆完成的 django-encrypted-idthis 撰写所以用户。但是,库最多支持 2^64 长整数并生成 24 个字符输出(22 + 2 填充)。这会导致我的嵌套结构中出现巨大的 URL。

因此,我想给加解密函数打个补丁,尽量缩短输出。这是原始代码(+ 我添加的填充处理):

# Remove the padding after encode and add it on decode
PADDING = '=='

def encode(the_id):
assert 0 <= the_id < 2 ** 64

crc = binascii.crc32(bytes(the_id)) & 0xffffff

message = struct.pack(b"<IQxxxx", crc, the_id)
assert len(message) == 16

cypher = AES.new(
settings.SECRET_KEY[:24], AES.MODE_CBC,
settings.SECRET_KEY[-16:]
)

return base64.urlsafe_b64encode(cypher.encrypt(message)).rstrip(PADDING)


def decode(e):
if isinstance(e, basestring):
e = bytes(e.encode("ascii"))

try:
e += str(PADDING)
e = base64.urlsafe_b64decode(e)
except (TypeError, AttributeError):
raise ValueError("Failed to decrypt, invalid input.")

for skey in getattr(settings, "SECRET_KEYS", [settings.SECRET_KEY]):
cypher = AES.new(skey[:24], AES.MODE_CBC, skey[-16:])
msg = cypher.decrypt(e)

crc, the_id = struct.unpack("<IQxxxx", msg)

if crc != binascii.crc32(bytes(the_id)) & 0xffffff:
continue

return the_id
raise ValueError("Failed to decrypt, CRC never matched.")

# Lets test with big numbers
for x in range(100000000, 100000003):
ekey = encode(x)
pk = decode(ekey)
print "Pk: %s Ekey: %s" % (pk, ekey)

输出(我稍微更改了字符串,所以不要试图破解我:P):

Pk: 100000000 Ekey: GNtOHji8rA42qfq3p5gNMI
Pk: 100000001 Ekey: tK6RcAZ2MrWmR3nB5qkQDe
Pk: 100000002 Ekey: a7VXIf8pEB6R7XvqwGQo6W

我试图修改 encode() 函数中的所有内容,但没有成功。生成的字符串的长度始终为 22。

这是我想要的:

  • 保持加密强度接近原始水平或至少不要大幅降低
  • 支持最大 2^48(~281 万亿)或 2^40 的整数,因为现在 2^64 太多了,我认为我们永远不会在数据库中拥有如此庞大的 PK。
  • 我对 14-20 之间的字符串长度感到满意。如果它是 20.. 那么是的,它仍然少 2 个字符..

最佳答案

目前您使用的是带有静态 IV 的 CBC 模式,因此您拥有的代码无论如何都不安全,并且如您所说,会产生相当大的密文。

我建议从 CBC 模式切换到 CTR 模式,这样您就可以拥有可变长度的 IV。我认为 CTR 模式下 IV(或随机数)的正常推荐长度是 12,但您可以根据需要向上或向下减少它。 CTR 也是一种流密码,这意味着就大小而言,输入的内容就是输出的内容。使用 AES,CBC 模式将始终以 16 字节为单位返回密文,因此即使您加密 6 字节,也会得到 16 字节,因此对您而言并不理想。

如果你让你的 IV 说...... 48 位长并且旨在加密不超过 48 位,你将能够产生 6 + 6 = 12 字节的原始输出,或使用 base64,(4* (12/3)) = 16 字节。通过进一步减小 IV 和/或输入大小(2^40?),您将能够获得比这更低的输出。您可以根据需要尽可能降低输入的可能值,而不会破坏安全性。

请记住,点击率确实存在缺陷。生成共享相同 IV 和 key 的两个密文意味着它们可以被轻易破解,因此请始终随机生成您的 IV(并且不要将其大小减小太多)。

关于python - 将整数(最多 2^48)安全加密为最短的 URL 安全字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42426584/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com