【问题标题】:Is it possible to use the GPU to accelerate hashing in Python?是否可以使用 GPU 来加速 Python 中的散列?
【发布时间】:2012-04-07 20:14:03
【问题描述】:

我最近阅读了 Jeff 题为 Speed Hashing 的博客文章,其中他提到您可以通过利用 GPU 的力量非常快速地对事物进行哈希处理。

我想知道是否可以利用 GPU 的力量在 Python(md5、sha-1 等)中对事物进行哈希处理?

我对此很感兴趣,因为我想看看我能以多快的速度暴力破解事物(不是现实世界的东西,来自旧的泄露数据转储)。

目前,我正在做这种事情(简化示例):

from itertools import product
from hashlib import md5

hashes = ["some","hashes"]

chars = []
for i in range(97,123): # a-z only
    chars.append(chr(i))

for i in range(1,6): # all combos of a-z, 1-5 chars
    for c in product(chars,repeat=i):
       s = ''.join(c)
       if md5(s).hexdigest() in hashes:
           print "Found",s

但我想知道是否有办法使用 GPU 加快速度?我猜我需要一个可以像这样连续生成哈希的模块 - 有人知道吗?

【问题讨论】:

  • 大多数哈希是不可并行的。因此,散列单个项目不会获得任何加速。但是如果你正在做很多哈希,(比如如果你在暴力破解某些东西),那么肯定......
  • @Mysticial - 是的,我正在使用itertools.product 生成字符数组的组合,然后对每次迭代进行哈希处理。
  • 我想知道这与 Python 有什么关系。如果要求的话,您不能使用 Python 对 GPU 进行编程。您需要使用(某种)C 或汇编语言编写实际算法,使用 GPU 的本机编程接口(在 nVidia 的情况下为 CUDA)或像 OpenCL 这样的元语言。
  • @NiklasB。 - 我想我正在为此寻找一个python模块。我知道 pygpu,但那是用于图像处理的。
  • @Alex:Python 模块做什么?你需要更具体。

标签: python hash gpu


【解决方案1】:

有两个障碍:

  1. 编写要在 GPU 上执行的程序。 AFAIK,目前没有可用于将 Python 程序转换为 GPU 执行的代码的机制。所以除非你能找到你需要的东西(这可能是可能的,因为它看起来是一个相当常见的用例),那么你将不得不使用其中一种 GPU 编程语言(CUDA、OpenCL、Haskell、.. .)
  2. 从 Python 调用在 GPU 上运行的程序,并交换数据。有几个 Python+CUDA 项目可以做到这一点:

    通过适当的搜索,您可能会找到更多。

    Python GPU programming 看起来也很相关

    然后,Python 程序将使用第 2 部分中的技术之一或同等技术加载并调用 GPU“内核”(使用本答案第 1 部分中的技术创建的程序)。

编辑 您可能会在 GPU 上生成整个“蛮力”值集和 md5 哈希值。然后只需使用 Python 检索结果。这可能比在 Python 中生成值、将它们传递给 GPU、然后取回 md5 更容易。

如果我理解的话,程序会生成所有 1 个字符、2、3、4、5 和 6 个小写字母的字符串,并生成 md5 哈希,是吗?


Edit2 - 我之前的分析完全错误 - 我道歉


Edit3:略读Wikipedia MD5 看起来可以优化为恒定长度字符串(例如 6 个 ASCII 字符)计算 MD5。

根据维基百科的伪代码,它只有 64 个循环,每组 16 个循环迭代使用相同的算法。因此,如果密钥小于 55 字节,则计算的核心可以从以下位置“展开”:

for i from 0 to 63
    if 0 ≤ i ≤ 15 then
        f := (b and c) or ((not b) and d)
        g := i
    else if 16 ≤ i ≤ 31
        f := (d and b) or ((not d) and c)
        g := (5×i + 1) mod 16
    else if 32 ≤ i ≤ 47
        f := b xor c xor d
        g := (3×i + 5) mod 16
    else if 48 ≤ i ≤ 63
        f := c xor (b or (not d))
        g := (7×i) mod 16
    temp := d
    d := c
    c := b
    b := b + leftrotate((a + f + k[i] + w[g]) , r[i])
    a := temp
end for

到:

// i == 0
f := (b and c) or ((not b) and d)   // +4 ops
// g := i
temp := d
d := c
c := b
b := b + leftrotate((a + f + k[0] + w[0]) , r[0])  // 9 ops
a := temp
// i == 1
f := (b and c) or ((not b) and d)
// g := i
temp := d
d := c
c := b
b := b + leftrotate((a + f + k[1] + w[1]) , r[1])
a := temp

这种展开会导致一些数组索引保持不变,这应该允许一个好的 GPU 编译器进行更恒定的传播。这可能会带来显着的改善。每一步大约是 9 次操作,编译器需要 shuffle 5 条数据,所以大约 14 操作/步 * 64 步,大约 1000 次操作。

编辑4:
Glerk! 我已经阅读了更多 Wikipedia MD5 算法 - MD5 比我想象的更容易攻击。每组16个直接只有前两个循环使用了6字节的可变key字符串,其余的字符串是常量。该算法的其余部分是改组和逐位操作,这很可能会进行非常重要的进一步优化。每 16 个循环中只有 2 个涉及密钥,那么这可能快 8 倍,甚至可能超过 4 倍。

因此,不是 1024 核 GPU,以 1GHz 运行,提供 1024 哈希/微秒,而是说 4096/微秒或 8096/us = 4-8 哈希/纳秒

大约有 27^6 个键 = 387,420,489 个键,因此是 md5 哈希。

387,420,489 键 / 4-8/纳秒大约 = 0.05 - 0.1 秒

主机和 GPU 之间的通信会很慢,但不太可能超过 100%。

所以大约在 0.1 秒到 0.2 秒之间。

一个 md5 哈希是 16 个字节,因此如果要存储它会消耗 6.2 GB。在两个现代 GPU 上,每个只需要 2 次传输,但这将是一个非常显着的开销。如果散列值被保存到磁盘(即使使用 SSD),或者通过 10Gbit 以太网移动,散列生成会被 I/O 时间淹没。

只有 94 个可打印的 ASCII 字符,所以对于每个 ASCII 6 字符键:

94^6 = 689,869,781,056 键 / 4-8/纳秒 = 86-172 秒

天哪!-(

长键,比 MD5 更好的东西!

也许尝试编写一个 Python 程序来生成最佳 GPU 算法?

通过“展开”Python程序中的循环生成GPU“内核”的文本,并打印直线计算的文本,并填写所有常量。

然后尝试找出最佳指令序列来计算每个密钥长度的 MD5。使用展开的程序,尝试跟踪每个位的操作和依赖关系,然后尝试将位及其操作重新组合成连续的 32 位字和新的直线计算。 (公平地说,也许 GPU 编译器无论如何都可以做到这一点?可能会很有趣)

【讨论】:

    猜你喜欢
    • 2012-03-07
    • 1970-01-01
    • 2023-01-28
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 2016-10-26
    • 2014-05-30
    相关资源
    最近更新 更多