【问题标题】:Restore corrupt 128-bit key from SHA-1从 SHA-1 恢复损坏的 128 位密钥
【发布时间】:2019-03-20 09:52:09
【问题描述】:

免责声明:这是大学作业的一部分

我收到了以下 AES-128-CBC 密钥,并告诉我密钥中最多 3 位已更改/损坏。

d9124e6bbc124029572d42937573bab4

提供原始密钥的 SHA-1 哈希;

439090331bd3fad8dc398a417264efe28dba1b60

我必须通过尝试最多 3 位翻转的所有组合来找到原始密钥。

据推测,这在 349633 次猜测中是可能的,但我不知道这个数字是从哪里来的;我会假设它会更接近 128*127*126,这将超过 2M 组合,这就是我的第一个问题所在。
其次,我在下面创建了包含三重嵌套循环的 python 脚本(我知道,远非最好的代码......)来迭代所有 2M 的可能性,但是,在一个小时后完成后,它没有找到我真正的匹配不明白。

希望有人能至少指出我正确的方向,干杯

#!/usr/bin/python2

import sys
import commands

global binary

def inverseBit(index):
    global binary
    if binary[index] == "0":
        return "1"
    return "0"

if __name__ == '__main__':
    if len(sys.argv) != 3:
        print "Usage: bitflip.py <hex> <sha-1>"
        sys.exit()

    global binary
    binary = ""

    sha = str(sys.argv[2])
    binary = str(bin(int(sys.argv[1], 16)))
    binary = binary[2:]
    print binary

    b2 = binary
    tries = 0
    file = open("shas", "w")

    for x in range(-2, 128):
        for y in range(-1,128):
            for z in range(0,128):
                if x >= 0:
                    b2 = b2[:x] + inverseBit(x) + b2[x+1:]
                if y >= 0:
                    b2 = b2[:y] + inverseBit(y) + b2[y+1:]
                b2 = b2[:z] + inverseBit(z) + b2[z+1:]
                #print b2
                hexOut = hex(int(b2,2))
                command = "echo -n \"" + hexOut + "\" | openssl sha1"
                cmdOut = str(commands.getstatusoutput(command))
                cmdOut = cmdOut[cmdOut.index('=')+2:]
                cmdOut = cmdOut[:cmdOut.index('\'')]
                file.write(str(hexOut) + " | " + str(cmdOut) + "\n")
                if len(cmdOut) != 40:
                    print cmdOut
                if cmdOut == sha:
                    print "Found bit reversals in " + str(tries) + " tries. Corrected key:"
                    print hexOut
                    sys.exit()
                b2 = binary
                tries = tries + 1
                if tries % 10000 == 0:
                    print tries

编辑:
将 for 循环更改为

for x in range(-2, 128):
            for y in range(x+1,128):
                for z in range(y+1,128):

在(我认为?)仍然覆盖整个空间的同时,大大减少了猜测的数量。仍然得到一些重复,但仍然没有运气找到匹配项..

【问题讨论】:

    标签: python encryption aes sha


    【解决方案1】:

    你的代码,虽然不是很高效,但除了一件事之外看起来还不错:

    hexOut = hex(int(b2,2))
    

    作为hex的输出

    >>> hex(int('01110110000101',2))
    '0x1d85'
    

    'Ox' 开头,它不应该是密钥的一部分。所以,去掉这两个字符应该没问题。

    对于可能尝试的键数,您有:

    • 1 没有位翻转
    • 128 位翻转 1 位
    • 128*127/2 = 8128 翻转 2 位(128 种方式选择第一个,127 种方式选择第二个,每对出现两次)
    • 128*127*126/6 = 341376 翻转 3 位(每个三元组出现 6 次)。这是 128 位的组合数,一次取 3 个。

    所以,总数是 1 + 128 + 8128 + 341376 = 349633 种可能性。

    您的代码对它们中的每一个进行了多次测试。您可以通过这样的循环(3位)来避免无用的重复:

    for x in range (0, 128):
        for y in range(x+1, 128):
            for z in range(y+1, 128):
                .....
    

    您可以调整从 -2 开始的技巧:

    for x in range (-2, 128):
        for y in range(x+1, 128):
            for z in range(y+1, 128):
                .... same code you used ...
    

    您还可以使用itertools.combinations 生成组合:

    from itertools import combinations
    for x, y, z in combinations(range(128), 3):  # for 3 bits
        ......
    

    但在这种情况下,您需要做更多的工作来管理具有 0、1、2 和 3 个翻转位的情况。

    【讨论】:

    • 干杯,删除 0x 工作。由于某种原因,还必须删除附加到所有十六进制值的尾随“L”。看起来我在你发帖前不久就找到了更好的循环方法,将它添加到你可能错过的编辑中:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 2016-05-26
    • 2016-06-06
    相关资源
    最近更新 更多