コード例 #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
コード例 #2
0
	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
コード例 #3
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
コード例 #4
0
def gen_DSA_per_message_secret(p, q):
	acceptable_pairs = [(1024, 160), (2048, 224), (2048, 256), (3072, 256)]

	N = len(bin(q)[2:])
	L = len(bin(p)[2:])

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

	c = utils.string_to_integer(os.urandom((N + 64) / 8))
	k = c % (q - 1) + 1

	k_inv = utils.invmod(k, q)
	return True, k, k_inv
コード例 #5
0
def DSA_gen_per_user_keys(p, q, g):
	acceptable_pairs = [(1024, 160), (2048, 224), (2048, 256), (3072, 256)]

	N = len(bin(q)[2:])
	L = len(bin(p)[2:])

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

	c = utils.string_to_integer(os.urandom((N + 64) / 8))
	x = c % (q - 1) + 1
	y = pow(g, x, p)

	return True, x, y
コード例 #6
0
def DSA_verify_signature(p, q, g, y, M, r, s, Hash, outlen):
	N = len(bin(q)[2:])

	if r <= 0 or r >= q or s <= 0 or s >= q:
		return False

	w = utils.invmod(s, q)
	z = utils.string_to_integer(Hash(M)[: min(N, outlen) / 8])
	u1 = (z * w) % q
	u2 = (r * w) % q
	v = ((pow(g, u1, p) * pow(y, u2, p)) % p) % q

	if v == r:
		return True

	return False
コード例 #7
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)
コード例 #8
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)
コード例 #9
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
コード例 #10
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
コード例 #11
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
コード例 #12
0
def DSA_gen_signature(p, q, g, x, M, Hash, outlen):
	N = len(bin(q)[2:])

	while True:
		status, k, k_inv = gen_DSA_per_message_secret(p, q)
		
		if status == False:
			return False, None, None
	
		r = pow(g, k, p) % q
	
		if r == 0:
			continue

		z = utils.string_to_integer(Hash(M)[: min(N, outlen) / 8])	# Leftmost min(N, outlen) bits of Hash(M)
		s = (k_inv * (z + x * r)) % q

		if s == 0:
			continue

		break

	return True, r, s
コード例 #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
コード例 #14
0
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
コード例 #15
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)
コード例 #16
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)
コード例 #17
0
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))