在Python中实现盗窃术(设置攻击)
我的任务是重现下面的情节: 它来自(第137-145页) 在中,作者描述了一种称为针对Diffie-Hellman密钥交换的窃贼攻击。特别是,他们编写了以下算法: 现在,作者认为“也许我们可以实现诚实的DHKE和恶意的DHKE,然后比较两种算法的运行时间”。然后,创建了上面的绘图。为此,他们说 “我们已经在ANSI C中实现了Diffie-Hellman协议的污染版本和未污染版本,并使用GNU C v 2.7编译器与RSAREF 2.0库相链接。所有测试都是在Linux系统上运行的,使用的计算机带有奔腾II处理器(350 MHz)和64 Mb内存。单个协议的计算时间以10-2秒为单位。” 我想做同样的事情,即实施善恶DH并比较运行时间。这是我产生的代码:在Python中实现盗窃术(设置攻击),python,cryptography,public-key-encryption,diffie-hellman,Python,Cryptography,Public Key Encryption,Diffie Hellman,我的任务是重现下面的情节: 它来自(第137-145页) 在中,作者描述了一种称为针对Diffie-Hellman密钥交换的窃贼攻击。特别是,他们编写了以下算法: 现在,作者认为“也许我们可以实现诚实的DHKE和恶意的DHKE,然后比较两种算法的运行时间”。然后,创建了上面的绘图。为此,他们说 “我们已经在ANSI C中实现了Diffie-Hellman协议的污染版本和未污染版本,并使用GNU C v 2.7编译器与RSAREF 2.0库相链接。所有测试都是在Linux系统上运行的,使用的计
import timeit #used to measure the running time of functions
import matplotlib.pyplot as plt #plot the results
import random
import numpy as np
import pyDH #library for Diffie-Hellman key exchange
X= pyDH.DiffieHellman() #Eve's private key
Y= X.gen_public_key() #Eve's public key
#The three integers a,b,W embedded by Eve
W=3
a=2
b=2
#Honest DH
def public_key():
d1 = pyDH.DiffieHellman()
return d1.gen_public_key()
#Malicoius Diffie_Hellman (SETUP) #line 1-7 in the algorithm
def mal_public_key():
d1 = pyDH.DiffieHellman().get_private_key()
t=random.choice([0,1])
z1=pow(pyDH.DiffieHellman().g,d1-W*t,pyDH.DiffieHellman().p)
z2=pow(Y,-a*d1-b,pyDH.DiffieHellman().p)
z= z1*z2 % pyDH.DiffieHellman().p
d2=hash(z)
return pow(pyDH.DiffieHellman().g,d2,pyDH.DiffieHellman().p)
#function that plot the results
def plot(ntest=100000):
times = []
times2=[]
for i in range(ntest):
#Running time HONEST Diffie-Hellman (worked two times = two key generations)
elapse_time = timeit.timeit(public_key, number=2)
#here I collect the times
times += [int(round(elapse_time* pow(10, 2) ) )]
# Running time MALICOIUS Diffie-Hellman
elapse_time2 = timeit.timeit(mal_public_key, number= 1)
times2 += [int(round(elapse_time2* pow(10, 2)) )]
x_axis=[i for i in range(0,20)]
#collect how many tests last i seconds
y_axis = [times.count(i) for i in x_axis]
y_axis2 = [times2.count(i) for i in x_axis]
plt.plot(x_axis, y_axis, x_axis, y_axis2)
plt.show()
plot()
我曾经在那里做过诚实的迪菲·赫尔曼。这个代码给了我这个数字:
我认为蓝线(诚实DH)是可以的,但我对橙色线(设置DH)有点怀疑,橙色线与此功能相关:
def mal_public_key(): #line 1-7 in the algorithm
d1 = pyDH.DiffieHellman().get_private_key()
t=random.choice([0,1])
z1=pow(pyDH.DiffieHellman().g,d1-W*t,pyDH.DiffieHellman().p)
z2=pow(Y,-a*d1-b,pyDH.DiffieHellman().p)
z= z1*z2 % pyDH.DiffieHellman().p
d2 = hash(z)
return pow(pyDH.DiffieHellman().g,d2,pyDH.DiffieHellman().p)
mal\u public\u key()
功能不好
我正在使用Windows10 64位、8Gb内存、AMD A10-8700P radeon R6、10个计算核心4C+6G 1.80GHz,其中我使用的是Python 3.8。我知道我的电脑应该比作者的好(我想)。也许这会影响结果。然而,在一条椭圆曲线上进行了一个类似的实验,结果与原始曲线很接近(但它是一条椭圆曲线)
(另一方面,我假设
a=b=2
和W=3
,因为Young和Young没有说明这些整数应该是什么)。通过一个具体的例子最容易理解这个问题:Alice有一个为她生成Diffie-Hellman键的设备。在该设备上实现了恶意Diffie-Hellman变体
恶意DH变体/设置的实现
恶意DH变体的定义如下:,秒。3.1:
MDH1:对于第一个生成的密钥对,以下内容适用:
- 私钥c1是小于p-1的随机值。c1储存起来以备日后使用
- 公钥根据m1=gc1 mod p计算
- 该设备向Alice提供私钥(c1)和公钥(m1)
- 随机选择一个t(0或1)
- z2根据z2=g(c1-Wt)*Y(-ac1-b)mod p计算
- 私钥c2根据H(z2)计算。这里H是一个加密散列函数。c2储存起来供以后使用
- 公钥根据m2=gc2 mod p计算
- 该设备为Alice提供私钥(c2)和公钥(m2)
- 随机选择一个t(0或1)
- zi根据zi=g(ci-1-Wt)*Y(-aci-1-b)mod p计算
- 私钥ci根据H(zi)计算。这里H是(相同的)加密散列函数。ci被存储以供以后使用
- 公钥根据mi=gci mod p计算
- 设备为Alice提供私钥(ci)和公钥(mi)
设置(具有通用保护的秘密嵌入式活板门)不是通过问题中发布的恶意DH变体实施的。
安装程序在两个连续生成的密钥对之间建立关系。这使得可以从两个这样的相关公钥导出上一代密钥的私钥,这两个公钥可以在密钥交换过程中被截获。
但为此,必须在连续的密钥生成之间传递私钥,以便在最后一代密钥中使用它来建立这种关系。这不会发生在实现中,因此无法实现所需的关系。
从更技术的角度来看,实现失败的主要原因是MDH1和MDHi案例不是单独实现的,而是作为一个关闭的过程一起实现的。关闭,即在连续调用之间不存储私钥,因此无法传递。因此,实现的后续调用将生成彼此之间不具有所需关系的随机密钥对。
还请注意,从
import timeit
import matplotlib.pyplot as plt
import Crypto.Random.random
import hashlib
import pyDH
DH = pyDH.DiffieHellman()
xBytes = bytes.fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
X = int.from_bytes(xBytes, 'big') #Attacker's private key
Y = pow(DH.g, X, DH.p) #Attacker's public key
W = 3
a = 1
b = 2
...
privateKey = -1
def maliciousDH():
global privateKey
DH = pyDH.DiffieHellman()
if privateKey == -1:
privateKeyBytes = Crypto.Random.get_random_bytes(32)
privateKey = int.from_bytes(privateKeyBytes, 'big')
publicKey = pow(DH.g, privateKey, DH.p)
return publicKey
else:
t = Crypto.Random.random.choice([0,1])
z1 = pow(DH.g, privateKey - W*t, DH.p)
z2 = pow(Y, -a*privateKey - b, DH.p)
z = z1 * z2 % DH.p
privateKey = hashVal(z)
publicKey = pow(DH.g, privateKey, DH.p)
return publicKey
def hashVal(value):
valBytes = value.to_bytes((value.bit_length() + 7) // 8, 'big')
hashBytes = hashlib.sha256(valBytes).digest()
hashInt = int.from_bytes(hashBytes, 'big')
return hashInt
def maliciousDHRepeated(nRepeats):
for repeat in range(nRepeats):
publicKey = maliciousDH()
print('Key Exchange: {0}\nPublic Key: {1}\nPrivate Key: {2}\n'.format(repeat, publicKey, privateKey))
maliciousDHRepeated(5)
def determineSecrets():
# Bob's key pair
DH = pyDH.DiffieHellman()
privateKeyBob = DH.get_private_key()
publicKeyBob = DH.gen_public_key()
#Alice's key pair (from Key Exchange 4)
privateKeyAlice = 3330795034653139675928270510449092467425071094588264172648356254062467669676
publicKeyAlice = 2425486506974365273326155229800001628001265676036580545490312140179127686868492011994151785383963618955049941820322807563286674799447812191829716334313989776868220232473407985110168712017130778639844427996734182094558266926956379518534350404029678111523307272488057571760438620025027821267299005190378538083215345831756055838193240337363440449096741629258341463744397835411230218521658062737568519574165810330776930112569624066663275971997360960116063343238010922620695431389619027278076763449139206478745130163740678443228451977971659504896731844067323138748945493668050217811755122279988027033740720863980805941221
#Secrets
secretBob = pow(publicKeyAlice, privateKeyBob, DH.p)
secretAlice = pow(publicKeyBob, privateKeyAlice, DH.p)
print("Bob's secret: {0}\nAlices's secret: {1}\n".format(secretBob, secretAlice))
determineSecrets()
def stealPrivateKey(currentPublicKey, previousPublicKey):
r = pow(previousPublicKey, a, DH.p) * pow(DH.g, b, DH.p) % DH.p
u = previousPublicKey * pow(r, -X, DH.p) % DH.p
if currentPublicKey == pow(DH.g, hashVal(u), DH.p):
return hashVal(u)
v = u * pow(DH.g, -W, DH.p) % DH.p
if currentPublicKey == pow(DH.g, hashVal(v), DH.p):
return hashVal(v)
return -1
previousPublicKey = 10734077925995936749728900841226052313744498030619019606720177499132029904239020745125405126713523340876577377685679745194099270648038862447581601078565944941187694038253454951671644736332158734087472188874069332741118722988900754423479460535064533867667442756344440676583179886192206646721969399316522205542274029421077750159152806910322245234676026617311998560439487358561468993386759527957631649439920242228063598908755800970876077082845023854156477810356816239577567741067576206713910926615601025551542922545468685517450134977861564984442071615928397542549964474043544099258656296307792809119600776707470658907443
currentPublicKey = 2425486506974365273326155229800001628001265676036580545490312140179127686868492011994151785383963618955049941820322807563286674799447812191829716334313989776868220232473407985110168712017130778639844427996734182094558266926956379518534350404029678111523307272488057571760438620025027821267299005190378538083215345831756055838193240337363440449096741629258341463744397835411230218521658062737568519574165810330776930112569624066663275971997360960116063343238010922620695431389619027278076763449139206478745130163740678443228451977971659504896731844067323138748945493668050217811755122279988027033740720863980805941221
currentPrivateKey = stealPrivateKey(currentPublicKey, previousPublicKey)
print(currentPrivateKey)
def standardDH():
DH = pyDH.DiffieHellman()
privateKeyBytes = Crypto.Random.get_random_bytes(32)
privateKey = int.from_bytes(privateKeyBytes, 'big')
publicKey = pow(DH.g, privateKey, DH.p)
return publicKey
def plot(nTests = 1000, nKeyExPerTest = 10):
global privateKey
timesStandardDH = []
timesMaliciousDH = []
for test in range(nTests):
for keyExPerTest in range(nKeyExPerTest):
elapseTimeStandardDH = timeit.timeit(standardDH, number = 1)
timesStandardDH += [int(round(elapseTimeStandardDH * pow(10, 3) ) )]
privateKey = -1
for keyExPerTest in range(nKeyExPerTest):
elapseTimeMaliciousDH = timeit.timeit(maliciousDH, number = 1)
timesMaliciousDH += [int(round(elapseTimeMaliciousDH * pow(10, 3)) )]
x_axis=[i for i in range(0, 50)]
y_axisStandardDH = [timesStandardDH.count(i) for i in x_axis]
y_axisMaliciousDH = [timesMaliciousDH.count(i) for i in x_axis]
plt.plot(x_axis, y_axisStandardDH, x_axis, y_axisMaliciousDH)
plt.show()
plot()