Beispiel #1
0
def BreakDSA(m1, m2, publicKey, dsa_params):
    # m1 and m2 are interchangeable, but if you compute m1['s'] - m2['s']
    # (and the rest accordingly), you get a negative K, which is not valid
    # according to the spec, and our implementation hangs trying to sign
    # a message.
    k = rsa.invmod((m2['s'] - m1['s']), dsa_params['Q'])
    k *= (int(m2['m'], 16) - int(m1['m'], 16))

    top = (m1['s'] * k) - int(m1['m'], 16)
    bottom = rsa.invmod(m1['r'], dsa_params['Q'])
    privateKey = (top * bottom) % dsa_params['Q']

    # Derive the public key from the private key and compare it
    # with the one we know.
    testPub = dsa.modexp(dsa_params['G'], privateKey, dsa_params['P'])
    if testPub == publicKey:
        print('[**] Success!')
        print('K:', k)
        print('X:', privateKey)

        # Sign one of the two messages with the private key and compare
        # the signature with the one we got from the file.
        sig = dsa.dsa_sign(dsa_params['Q'],
                           dsa_params['P'],
                           dsa_params['G'],
                           privateKey,
                           int('0x' + m1['m'], 16),
                           k=k)
        if sig == (m1['r'], m1['s']):
            print('[**] Broken private key passes validation')
            return True

    return False
Beispiel #2
0
def dsa_parameter_tampering():

	# g = 0 % p
	# so r = 0 ** k mod p mod q == 0
	# normally r == 0 would be rejected, but let's assume that there is no error checking
	# then s = k ** -1 * H(m) mod q
	# Do not need secret key x to sign

	# g = p + 1
	bad_params, pub, priv = dsa.dsa_keygen(dsa.P, dsa.Q, dsa.P+1)
	p, q, g = bad_params
	z = 3
	z_inv = dsa.invmod(z, q)
	
	r = dsa.modexp(pub, z, p) % q
	s = r * z_inv % q

	# validate
	msg = 'Hello, world'
	print "Verifying %s " % msg
	print dsa.dsa_verify(bad_params, pub, msg, (r, s))

	# validate
	msg = 'Goodbye, world'
	print "Verifying %s " % msg
	print dsa.dsa_verify(bad_params, pub, msg, (r, s))
Beispiel #3
0
def BreakDSA(m1, m2, publicKey, dsa_params):
	# m1 and m2 are interchangeable, but if you compute m1['s'] - m2['s']
	# (and the rest accordingly), you get a negative K, which is not valid
	# according to the spec, and our implementation hangs trying to sign
	# a message.
	k = rsa.invmod((m2['s'] - m1['s']), dsa_params['Q'])
	k *= (int(m2['m'], 16) - int(m1['m'], 16))

	top = (m1['s'] * k) - int(m1['m'], 16)
	bottom = rsa.invmod(m1['r'], dsa_params['Q'])
	privateKey = (top * bottom) % dsa_params['Q']

	# Derive the public key from the private key and compare it
	# with the one we know.
	testPub = dsa.modexp(dsa_params['G'], privateKey, dsa_params['P'])
	if testPub == publicKey:
		print('[**] Success!')
		print('K:', k)
		print('X:', privateKey)

		# Sign one of the two messages with the private key and compare
		# the signature with the one we got from the file.
		sig = dsa.dsa_sign(dsa_params['Q'], dsa_params['P'], dsa_params['G'], privateKey,
						   int('0x' + m1['m'], 16), k=k)
		if sig == (m1['r'], m1['s']):
			print('[**] Broken private key passes validation')
			return True

	return False
Beispiel #4
0
def BreakDSA(p, g, q, r, s):
	publicKey = int('0x84ad4719d044495496a3201c8ff484feb45b962e7302e56a392aee4abab3e4bdebf2955b4736012f21a08084056b19bcd7fee56048e004e44984e2f411788efdc837a0d2e5abb7b555039fd243ac01f0fb2ed1dec568280ce678e931868d23eb095fde9d3779191b8c0299d6e07bbb283e6633451e535c45513b2d33c99ea17', 16)

	H = dsa.HashMessage(b'For those that envy a MC it can be hazardous to your health\n'
			        	b'So be friendly, a matter of life and death, just like a etch-a-sketch\n')

	k = 0
	brokenKey = None

	for k in range(1, 2 ** 16 + 1):
		top = (s * k) - H
		bottom = rsa.invmod(r, q)
		privateKey = (top * bottom) % q

		# Derive the public key from the private key and compare it
		# with the one we know.
		testPub = dsa.modexp(g, privateKey, p)
		if testPub == publicKey:
			brokenKey = privateKey
			break
	else:
		print('[!!] Unable to break private key')
		return

	print('[**] Success!')
	print('K:', k)
	print('X:', brokenKey)
	return brokenKey, k
Beispiel #5
0
def recover_dsa_nonce_repeated(params=(dsa.P, dsa.Q, dsa.G)):

	p, q, g = params

	# read messages
	f = open('44.txt','r')
	lines = f.readlines()
	f.close()


	y = '2d026f4bf30195ede3a088da85e398ef869611d0f68f07'+\
		'13d51c9c1a3a26c95105d915e2d8cdf26d056b86b8a7b8'+\
		'5519b1c23cc3ecdc6062650462e3063bd179c2a6581519'+\
		'f674a61f1d89a1fff27171ebc1b93d4dc57bceb7ae2430'+\
		'f98a6a4d83d8279ee65d71c1203d2c96d65ebbf7cce9d3'+\
		'2971c3de5084cce04a2e147821'

	y = long(y, 16)
	x_sha1 = 'ca8f6f7c66fa362d40760d135b763eb8527d3d52'

	# r = g^{k} mod p mod q
	# s = k ^ -1 * (H(m) + x*r) mod q

	# repeated k means that r is the same
	# s1 - s2 = k ^ -1 * (H(m1) - H(m2)) mod q
	# so k = (H(m1) - H(m2))/(s1 - s2) mod q

	# search for a repeated r
	r_dict = {}
	for i in range(0, len(lines), 4):
		msg = lines[i][5:].strip('\n')
		s = lines[i+1][2:].strip()
		r = lines[i+2][2:].strip()
		h = lines[i+3][2:].strip()

		if r in r_dict:
			print "Found repeated r =", r 
			# we found a repeat, so calculate k
			h1 = long(h, 16)
			s1 = long(s)
			
			s2, h2 = r_dict[r]

			h2 = long(h2, 16)
			s2 = long(s2)

			numerator = (h1 - h2) % q
			denominator = (s1 - s2) % q
			denom_inv = dsa.invmod(denominator, q)
			assert denom_inv

			k = (numerator * denom_inv) % q
			print "Found k: %d" % k

			r2 = dsa.modexp(g, k, p) % q
			print "Checking k ... ", long(r)==r2


			# calculate x, the private key

			x = dsa.recover_priv_from_k(params, k, msg, (long(r),long(s)))
			
			if x_sha1 == hashlib.sha1(binascii.hexlify(dsa._tohex(x))).hexdigest():
				print "Found x == %d" % x
				return
			else:
				print "Could not find correct x"

		r_dict[r] = (s, h)

	return "Could not find a repeated use of k"