Esempio n. 1
0
def gen_DSA_primes(L, N, seedlen, Hash, outlen):
    acceptable_pairs = [(1024, 160), (2048, 224), (2048, 256), (3072, 256)]

    if (L, N) not in acceptable_pairs:
        return False, None, None

    if seedlen < N:
        return False, None, None

    n = int(math.ceil(float(L) / float(outlen)) - 1)
    b = L - 1 - n * outlen

    while True:
        domain_parameter_seed = utils.string_to_integer(os.urandom(seedlen /
                                                                   8))
        U = utils.string_to_integer(
            Hash(utils.integer_to_string(domain_parameter_seed))) % 2**(N - 1)
        q = 2**(N - 1) + U + 1 - (U % 2)

        if not is_prime(q):
            continue

        offset = 1

        for counter in range(4 * L):
            V = {}

            for j in range(n + 1):
                V[j] = utils.string_to_integer(
                    Hash(
                        utils.integer_to_string(
                            (domain_parameter_seed + offset + j) %
                            2**seedlen)))

            W = sum([V[j] * 2**(j * outlen)
                     for j in range(n - 1)]) + (V[n] % 2**b) * 2**(n * outlen)
            X = W + 2**(L - 1)
            c = X % (2 * q)
            p = X - (c - 1)

            if p < 2**(L - 1):
                offset = offset + n + 1
                continue

            if is_prime(p):
                return True, p, q

            offset = offset + n + 1

    return False, None, None
Esempio n. 2
0
def test_sample_signature():
    # DSA domain parameters
    p = 0x800000000000000089e1855218a0e7dac38136ffafa72eda7859f2171e25e65eac698c1702578b07dc2a1076da241c76c62d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebeac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc871a584471bb1
    q = 0xf4f47f05794b256174bba6e9b396a7707e563c5b
    g = 0x5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119458fef538b8fa4046c8db53039db620c094c9fa077ef389b5322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a0470f5b64c36b625a097f1651fe775323556fe00b3608c887892878480e99041be601a62166ca6894bdd41a7054ec89f756ba9fc95302291

    # DSA public key
    y = 0x84ad4719d044495496a3201c8ff484feb45b962e7302e56a392aee4abab3e4bdebf2955b4736012f21a08084056b19bcd7fee56048e004e44984e2f411788efdc837a0d2e5abb7b555039fd243ac01f0fb2ed1dec568280ce678e931868d23eb095fde9d3779191b8c0299d6e07bbb283e6633451e535c45513b2d33c99ea17

    # Message
    msg = "For those that envy a MC it can be hazardous to your health\nSo be friendly, a matter of life and death, just like a etch-a-sketch\n"

    # DSA Signature
    r = 548099063082341131477253921760299949438196259240
    s = 857042759984254168557880549501802188789837994940

    # Check that message hash is correct.
    if SHA1_HASH(msg).encode(
            'hex') != "d2d0714f014a9784047eaeccf956520045c45265":
        print "Wrong SHA-1 hash for the sample message."
        return

    x, k = recover_private_key(p, q, g, r, s, msg, SHA1_HASH,
                               hashlib.sha1().block_size * 8)

    if x == None:
        print "Failed to recover DSA private key for sample message."
        return

    # Check that this x, k pair produces the same signature.
    status, r1, s1 = DSA_gen_signature_weak(p, q, g, x, msg, SHA1_HASH,
                                            hashlib.sha1().block_size * 8, k)

    if status == False or r1 != r or s1 != s:
        print "Failed to recover DSA private key for sample message."
        return

    # Check agains SHA-1 hash provided.
    if SHA1_HASH(utils.integer_to_string(x).encode('hex')).encode(
            'hex') != "0954edd5e0afe5542a4adf012611a91912a3ec16":
        print "Failed to recover DSA private key for sample message."
        return

    print "DSA private key for sample message: x = " + utils.integer_to_string(
        x).encode('hex')
def gen_DSA_primes(L, N, seedlen, Hash, outlen):
	acceptable_pairs = [(1024, 160), (2048, 224), (2048, 256), (3072, 256)]

	if (L, N) not in acceptable_pairs:
		return False, None, None

	if seedlen < N:
		return False, None, None

	n = int(math.ceil(float(L) / float(outlen)) - 1)
	b = L - 1 - n * outlen

	while True:
		domain_parameter_seed = utils.string_to_integer(os.urandom(seedlen / 8))
		U = utils.string_to_integer(Hash(utils.integer_to_string(domain_parameter_seed))) % 2 ** (N - 1)
		q = 2 ** (N - 1) + U + 1 - (U % 2)
	
		if not is_prime(q):
			continue

		offset = 1
	
		for counter in range(4 * L):
			V = {}
	
			for j in range(n + 1):
				V[j] = utils.string_to_integer(Hash(utils.integer_to_string((domain_parameter_seed + offset + j) % 2 ** seedlen)))
	
			W = sum([V[j] * 2 ** (j * outlen) for j in range(n - 1)]) + (V[n] % 2 ** b) * 2 ** (n * outlen)
			X = W + 2 ** (L - 1)
			c = X % (2 * q)
			p = X - (c - 1)
	
			if p < 2 ** (L - 1):
				offset = offset + n + 1
				continue
	
			if is_prime(p):
				return True, p, q

			offset = offset + n + 1

	return False, None, None
def RSASSA_PKCS1_v1_5_SIGN(n, d, M):
	k = (len(bin(n)[2:]) + 7) / 8	# Length of n in octets
	
	try:
		EM = EMSA_PKCS1_v1_5_ENCODE(M, k)
	except:
		raise Exception("RSA modulus too short")

	m = utils.string_to_integer(EM)
	s = utils.RSA_decrypt(m, n, d)
	S = utils.integer_to_string(s)
	return S
	def recover_plaintext(self):
		ciphertext = self.client.intercept_ciphertext()
		self.fetch_pubkey()

		message = self.submit_ciphertext(ciphertext)

		if message != None:
			print "Direct decryption worked... wtf?"
			return message

		c = utils.string_to_integer(ciphertext)
		s = random.randint(2, self.n - 1)
		new_c = (pow(s, self.e, self.n) * c) % self.n
		new_ciphertext = utils.integer_to_string(new_c)
		new_message = self.submit_ciphertext(new_ciphertext)
		new_p = utils.string_to_integer(new_message)

		p = (new_p * utils.invmod(s, self.n)) % self.n
		message = utils.integer_to_string(p)

		return message
Esempio n. 6
0
def RSASSA_PKCS1_v1_5_SIGN(n, d, M):
    k = (len(bin(n)[2:]) + 7) / 8  # Length of n in octets

    try:
        EM = EMSA_PKCS1_v1_5_ENCODE(M, k)
    except:
        raise Exception("RSA modulus too short")

    m = utils.string_to_integer(EM)
    s = utils.RSA_decrypt(m, n, d)
    S = utils.integer_to_string(s)
    return S
def crack_ciphertext(server, ciphertext, n, e):
	k = 0
	nbits = len(bin(n)[2:].strip('L'))

	for i in range(nbits):
		m = ((k + 1) * n) >> i
		printstr = to_printable(utils.integer_to_string(m))
		sys.stdout.write(printstr)
		sys.stdout.flush()
		ciphertext = double_plaintext(ciphertext, n, e)

		if server.parity_oracle(ciphertext) == True:
			k = 2 * k
		else:
			k = 2 * k + 1

		# Used for the "Hollywood" style printing
		sys.stdout.write("\b" * len(printstr))
		sys.stdout.write(" " * len(printstr))
		sys.stdout.write("\b" * len(printstr))
		sys.stdout.flush()

	m = ((k + 1) * n) >> nbits
	return utils.integer_to_string(m)
Esempio n. 8
0
def crack_ciphertext(server, ciphertext, n, e):
    k = 0
    nbits = len(bin(n)[2:].strip('L'))

    for i in range(nbits):
        m = ((k + 1) * n) >> i
        printstr = to_printable(utils.integer_to_string(m))
        sys.stdout.write(printstr)
        sys.stdout.flush()
        ciphertext = double_plaintext(ciphertext, n, e)

        if server.parity_oracle(ciphertext) == True:
            k = 2 * k
        else:
            k = 2 * k + 1

        # Used for the "Hollywood" style printing
        sys.stdout.write("\b" * len(printstr))
        sys.stdout.write(" " * len(printstr))
        sys.stdout.write("\b" * len(printstr))
        sys.stdout.flush()

    m = ((k + 1) * n) >> nbits
    return utils.integer_to_string(m)
Esempio n. 9
0
def forge_signature(data, n, e):
    k = (len(bin(n)[2:]) + 7) / 8
    b = 8 * k

    H = SHA256_HASH(data)
    ASN1_GOOP = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"
    D = utils.string_to_integer(ASN1_GOOP + H)

    N = 2**416 - D  # 32 (HASH) + 19 (ASN1_GOOP) + 1 (\x00) = 52 ---> 416 bits
    X = b - 440  # N * 2^X < 2^(b - 15 - 8) (Need 8 bits padding "\xff" at least), and need multiple of 8.
    MAX_GARBAGE = 2**X - 1

    # By picking MAX_GARBAGE as high as possible, we are most likely to find a cube root
    # whose cube is within the range that starts with the desired bytes.
    MAX_S3 = 2**(b - 15) - N * 2**X + MAX_GARBAGE
    s = cube_root(MAX_S3)

    return utils.integer_to_string(s, k)
def forge_signature(data, n, e):
	k = (len(bin(n)[2:]) + 7) / 8
	b = 8 * k

	H = SHA256_HASH(data)
	ASN1_GOOP = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"
	D = utils.string_to_integer(ASN1_GOOP + H)

	N = 2 ** 416 - D	# 32 (HASH) + 19 (ASN1_GOOP) + 1 (\x00) = 52 ---> 416 bits
	X = b - 440		# N * 2^X < 2^(b - 15 - 8) (Need 8 bits padding "\xff" at least), and need multiple of 8.
	MAX_GARBAGE = 2 ** X - 1

	# By picking MAX_GARBAGE as high as possible, we are most likely to find a cube root
	# whose cube is within the range that starts with the desired bytes.
	MAX_S3 = 2 ** (b - 15) - N * 2 ** X + MAX_GARBAGE
	s = cube_root(MAX_S3)

	return utils.integer_to_string(s, k)
Esempio n. 11
0
def check_signature_weak(n, e, M, S):
    k = (len(bin(n)[2:]) + 7) / 8  # Length of n in octets

    if len(S) != k:
        return False

    s = utils.string_to_integer(S)
    m = pow(s, e, n)

    try:
        EM = utils.integer_to_string(m, k)
    except:
        return False

    H = SHA256_HASH(M)
    ASN1_GOOP = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"
    T = ASN1_GOOP + H

    if re.match("\x00\x01" + "[\xff]+" + "\x00" + re.escape(T), EM):
        return True

    return False
def check_signature_weak(n, e, M, S):
	k = (len(bin(n)[2:]) + 7) / 8	# Length of n in octets

	if len(S) != k:
		return False

	s = utils.string_to_integer(S)
	m = pow(s, e, n)

	try:
		EM = utils.integer_to_string(m, k)
	except:
		return False

	H = SHA256_HASH(M)
	ASN1_GOOP = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"
	T = ASN1_GOOP + H

	if re.match("\x00\x01" + "[\xff]+" + "\x00" + re.escape(T), EM):
		return True

	return False
Esempio n. 13
0
def RSASSA_PKCS1_v1_5_VERIFY(n, e, M, S):
    k = (len(bin(n)[2:]) + 7) / 8  # Length of n in octets

    if len(S) != k:
        return False

    s = utils.string_to_integer(S)
    m = pow(s, e, n)

    try:
        EM_ = utils.integer_to_string(m, k)
    except:
        return False

    try:
        EM = EMSA_PKCS1_v1_5_ENCODE(M, k)
    except:
        raise Exception("RSA modulus too short")

    if EM == EM_:
        return True

    return False
def RSASSA_PKCS1_v1_5_VERIFY(n, e, M, S):
	k = (len(bin(n)[2:]) + 7) / 8	# Length of n in octets

	if len(S) != k:
		return False

	s = utils.string_to_integer(S)
	m = pow(s, e, n)

	try:
		EM_ = utils.integer_to_string(m, k)
	except:
		return False

	try:
		EM = EMSA_PKCS1_v1_5_ENCODE(M, k)
	except:
		raise Exception("RSA modulus too short")

	if EM == EM_:
		return True

	return False
Esempio n. 15
0
def test_weak_signature():
    msg = "Talk to the hand."
    status, p, q, g = dsa.DSA_gen_domain_params(2048, 256, 2048, SHA1_HASH,
                                                hashlib.sha1().block_size * 8)

    if status == False:
        print "Failed to generate DSA domain parameters."
        return

    status, x, y = dsa.DSA_gen_per_user_keys(p, q, g)

    if status == False:
        print "Failed to generate DSA per-user keys."
        return

    status, r, s = DSA_gen_signature_weak(p, q, g, x, msg, SHA1_HASH,
                                          hashlib.sha1().block_size * 8)

    if status == False:
        print "Failed to generate weak DSA signature."
        return

    if dsa.DSA_verify_signature(p, q, g, y, msg, r, s, SHA1_HASH,
                                hashlib.sha1().block_size * 8) == False:
        print "Failed to verify DSA signature."
        return

    x1, k = recover_private_key(p, q, g, r, s, msg, SHA1_HASH,
                                hashlib.sha1().block_size * 8)

    if x == None or x1 != x:
        print "Could not recover DSA private key for weak signature."
        return

    print "Successfully recovered DSA private key for weak signature: x = " + utils.integer_to_string(
        x1).encode('hex')
def recover_x_from_k(q, k, r, s, msg, Hash, outlen):
	N = len(bin(q)[2:])
	x = (((s * k) - utils.string_to_integer(Hash(msg)[: min(N, outlen) / 8])) * utils.invmod(r, q)) % q

	return x

# DSA domain parameters
p = 0x800000000000000089e1855218a0e7dac38136ffafa72eda7859f2171e25e65eac698c1702578b07dc2a1076da241c76c62d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebeac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc871a584471bb1
q = 0xf4f47f05794b256174bba6e9b396a7707e563c5b
g = 0x5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119458fef538b8fa4046c8db53039db620c094c9fa077ef389b5322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a0470f5b64c36b625a097f1651fe775323556fe00b3608c887892878480e99041be601a62166ca6894bdd41a7054ec89f756ba9fc95302291

# DSA public key
y = 0x2d026f4bf30195ede3a088da85e398ef869611d0f68f0713d51c9c1a3a26c95105d915e2d8cdf26d056b86b8a7b85519b1c23cc3ecdc6062650462e3063bd179c2a6581519f674a61f1d89a1fff27171ebc1b93d4dc57bceb7ae2430f98a6a4d83d8279ee65d71c1203d2c96d65ebbf7cce9d32971c3de5084cce04a2e147821

f = open('44.txt', 'r')
data = f.read()
f.close()

signatures = parse_signatures(data)
repeated_sigs = find_signatures_with_same_k(signatures)
k = find_k_from_repeated_sigs(q, repeated_sigs)
r = repeated_sigs[0]['r']
s = repeated_sigs[0]['s']
msg = repeated_sigs[0]['msg']
x = recover_x_from_k(q, k, r, s, msg, SHA1_HASH, hashlib.sha1().block_size * 8)

if SHA1_HASH(utils.integer_to_string(x).encode('hex')).encode('hex') == "ca8f6f7c66fa362d40760d135b763eb8527d3d52":
	print "Found private key x = " + utils.integer_to_string(x).encode('hex')
else:
	print "Failed to find private key."
def Bleichenbacher_attack(server, ciphertext, n, e):
	k = (len(bin(n)[2:].strip('L')) + 7) / 8
	B = 2 ** (8 * (k - 2))
	c = utils.string_to_integer(ciphertext)

	# Step 1 (skip blinding)
	si = 1
	c0 = c
	Mi = [[2 * B, 3 * B - 1]]
	i = 1

	while True:
		si_1 = si
		Mi_1 = Mi

		# Step 2
		if i == 1:
			# Step 2.a
			si = (n + 3 * B - 1) / (3 * B)	# ceil(n / (3B))

			while server.padding_oracle(utils.integer_to_string((c0 * pow(si, e, n)) % n)) != True:
				si += 1
		elif len(Mi) >= 2:
			# Step 2.b
			si = si_1 + 1

			while server.padding_oracle(utils.integer_to_string((c0 * pow(si, e, n)) % n)) != True:
				si += 1
		else:
			# Step 2.c
			a = Mi[0][0]
			b = Mi[0][1]

			ri = (2 * b * si_1 - 2 * B + n - 1) / n	# ceil((2 * b * si_1 - 2 * B) / n)
			conforming = False

			while not conforming:
				for si in range((2 * B + ri * n + b - 1) / b, (3 * B - 1 + ri * n) / a + 1):
					if server.padding_oracle(utils.integer_to_string((c0 * pow(si, e, n)) % n)) == True:
						conforming = True
						break
				else:
					ri += 1

		# Step 3
		Mi = []

		for Ir in Mi_1:
			a = Ir[0]
			b = Ir[1]

			for r in range((a * si - 3 * B + 1 + n - 1) / n, (b * si - 2 * B) / n + 1):
				new_a = max(a, (2 * B + r * n + si - 1) / si)	# to get the ceiling
				new_b = min(b, (3 * B - 1 + r * n) / si)

				if new_b >= new_a:
					Mi.append([new_a, new_b])

		# Step 4
		if len(Mi) == 1 and Mi[0][0] == Mi[0][1]:
			m = Mi[0][0]
			break

		i += 1
	
	return PKCS1_v1_5_Unpad(utils.integer_to_string(m, k))
Esempio n. 18
0
def double_plaintext(cipher, n, e):
    c = utils.string_to_integer(cipher)
    c = (c * pow(2, e, n)) % n
    return utils.integer_to_string(c)
def double_plaintext(cipher, n, e):
	c = utils.string_to_integer(cipher)
	c = (c * pow(2, e, n)) % n
	return utils.integer_to_string(c)