初识差分攻击

  1. 介绍
  2. 例题

介绍

一种密码分析技术,它利用明文对之间的差异来破解密码系统。攻击者通过对一系列明文对进行分析,找到它们之间的差异,并将这些差异与相应的密文对应起来,以获得加密密钥或破解密码系统。在块密码中用的比较多。

例题

from secret import flag


def s_substitute(m):
    c = 0
    s_box = {0: 0x6, 1: 0x4, 2: 0xc, 3: 0x5, 4: 0x0, 5: 0x7, 6: 0x2, 7: 0xe, 8: 0x1, 9: 0xf, 10: 0x3, 11: 0xd, 12: 0x8,
             13: 0xa, 14: 0x9, 15: 0xb}
    for i in range(0, 16, 4):
        t = (m >> i) & 0xf
        t = s_box[t]
        c += t << i
    return c


def enc(m, key):
    n = len(key)
    t = m
    for i in range(n - 1):
        t = t ^ key[i]
        t = s_substitute(t)
    c = t ^ key[n - 1]
    return c


f = flag[6:-1]
assert flag == 'hgame{' + f + '}'
key = [int(i, 16) for i in f.split('_')]
print(len(key))
m_list = [i * 0x1111 for i in range(16)]
c_list = [enc(m, key) for m in m_list]
print(c_list)

# 5
# [28590, 33943, 30267, 5412, 11529, 3089, 46924, 59533, 12915, 37743, 64090, 53680, 18933, 49378, 23512, 44742]

属于差分攻击里的四轮S盒差分攻击。

密钥由16进制数字组成的列表构成,共有5个元素。将每个元素按照4位一组进行分组,得到5组4位16进制数,然后将这些数作为输入,得到相应的输出。测试发现,这些输出是固定不变的。

每个元素只有4位,因此一共有16种可能性。可以枚举每一种可能性,然后将它们组合成5个元素的列表,依次进行加密操作,直到得到和实际密文一致的结果。由于每个元素只有16种可能性,因此总共需要尝试 $16^5=4194304$ 种可能性。

from tqdm import *
from itertools import product

m = [0, 4369, 8738, 13107, 17476, 21845, 26214, 30583, 34952, 39321, 43690, 48059, 52428, 56797, 61166, 65535]
c = [28590, 33943, 30267, 5412, 11529, 3089, 46924, 59533, 12915, 37743, 64090, 53680, 18933, 49378, 23512, 44742]
m = [[(k >> i) & 0xf for i in range(0, 16, 4)] for k in m]
c = [[(k >> i) & 0xf for i in range(0, 16, 4)] for k in c]
#print(m)
#print(c)

m = [[k[i] for k in m] for i in range(4)]
c = [[k[i] for k in c] for i in range(4)]
print(m)
print(c)

def s_substitute(m):
    c = 0
    s_box = {0: 0x6, 1: 0x4, 2: 0xc, 3: 0x5, 4: 0x0, 5: 0x7, 6: 0x2, 7: 0xe, 8: 0x1, 9: 0xf, 10: 0x3, 11: 0xd, 12: 0x8,
             13: 0xa, 14: 0x9, 15: 0xb}
    for i in range(0, 16, 4):
        t = (m >> i) & 0xf
        t = s_box[t]
        c += t << i
    return c

def enc(m, key):
    n = len(key)
    t = m
    for i in range(n - 1):
        t = t ^ key[i]
        t = s_substitute(t)
    c = t ^ key[n - 1]
    return c

m_list = [i * 0x1111 for i in range(16)]
finalkey = ['']*5

dic = '0123456789abcdef'
allc = list(product(dic,repeat=5))
for i in range(4):
    for k in tqdm(allc):
        key = [(int(x, 16))<<(4*i) for x in k]
        c_list = [enc(m, key) for m in m_list]
        out = [(k >> (4*i)) & 0xf for k in c_list]
        if out == c[i]:
            print(i,k)
            for j in range(5):
                finalkey[j] = k[j] + finalkey[j]
            break

print('hgame{'+'_'.join(finalkey)+'}')

# 0 ('2', '3', '2', '0', '5')
# 1 ('4', '9', '9', '7', 'd')
# 2 ('f', '4', 'f', '5', '8')
# 3 ('4', 'f', '4', '4', 'd')

有点无法理解,头大😵

参考:HGAME 2023 Week 3 | Lazzaro (lazzzaro.github.io)


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1666739907@qq.com
github