class RSA_Signature_PKCS_1_5:
    def __init__(self, s, e=3):
        self.key = RSA(s, e=e)
        self.key.generate_keys()

        self.key_length_bytes = s / 8

    def sign(self, message):
        h = hashlib.sha1(message).hexdigest()
        to_sign = '0001' + 'ff' * (self.key_length_bytes -
                                   38) + '00' + ASN1_SHA1 + h
        to_sign_integer = rsa_string_to_integer(to_sign.decode('hex'))

        signature = self.key.decrypt(to_sign_integer, encode=False)
        return signature

    def insecure_verify(self, signature, message):
        m = self.key.encrypt(signature, encode=False)
        m = rsa_integer_to_string(m).encode('hex')
        m = '00' * (self.key_length_bytes - len(m) / 2) + m

        h = hashlib.sha1(message).hexdigest()
        regex = '0001(ff)*00' + ASN1_SHA1 + h
        if re.search(regex, m) is not None:
            return True
        else:
            return False
    def __init__(self, s, e=65537):
        self.key = RSA(s, e=e)
        self.key.generate_keys()  # replace RSA params

        self.key.p = getPrime(128)
        self.key.q = getPrime(128)
        self.key.N = self.key.p * self.key.q

        self.key.et = (self.key.p - 1) * (self.key.q - 1)

        self.key.d = modinv(self.key.e, self.key.et)
        assert self.key.d is not None, 'modinv failed'

        self.key.public_key = (self.key.N, self.key.e)
        self.key.private_key = (self.key.N, self.key.d)

        #self.key_length_bytes = s / 8
        self.key_length_bytes = (len(bin(self.key.N)[2:-1]) + 7) / 8
    def __init__(self, s, e=3):
        self.key = RSA(s, e=e)
        self.key.generate_keys()

        self.key_length_bytes = s / 8
class RSA_PKCS_1_5:
    def __init__(self, s, e=65537):
        self.key = RSA(s, e=e)
        self.key.generate_keys()  # replace RSA params

        self.key.p = getPrime(128)
        self.key.q = getPrime(128)
        self.key.N = self.key.p * self.key.q

        self.key.et = (self.key.p - 1) * (self.key.q - 1)

        self.key.d = modinv(self.key.e, self.key.et)
        assert self.key.d is not None, 'modinv failed'

        self.key.public_key = (self.key.N, self.key.e)
        self.key.private_key = (self.key.N, self.key.d)

        #self.key_length_bytes = s / 8
        self.key_length_bytes = (len(bin(self.key.N)[2:-1]) + 7) / 8

    def pad_pkcs(self, message):
        padding_string_length = self.key_length_bytes - 3 - len(message)
        padding_string = crypto_non_zero_random_bytes(padding_string_length)
        padded = bytearray([0, 2]) + padding_string + bytearray(
            [0]) + bytearray(message)

        assert len(padded) == self.key_length_bytes, 'padding failed'
        return padded

    def unpad_pkcd(self, message):
        assert len(message) == self.key_length_bytes, 'cannot begin unpadding'
        #print list(message)

        if message[0] != 0 or message[1] != 2:
            raise Exception('invalid pkcs#1 padding')

        i = 2
        while message[i] != 0:
            i += 1

        return message[i + 1:]

    def encrypt(self, message):
        padded = self.pad_pkcs(message)
        i = bytes_to_integer(padded)

        return self.key.encrypt(i, encode=False)

    def decrypt(self, ciphertext):
        m_int = self.key.decrypt(ciphertext, encode=False)
        m = integer_to_bytes(m_int, self.key_length_bytes)
        unpadded = self.unpad_pkcd(m)

        return unpadded

    def encrypt_no_pkcs(self, message):
        i = bytes_to_integer(message)
        return self.key.encrypt(i, encode=False)

    def decrypt_no_pkcs(self, ciphertext):
        m_int = self.key.decrypt(ciphertext, encode=False)
        m = integer_to_bytes(m_int, self.key_length_bytes)

        return m
示例#5
0
def encrypt_broadcast_message(message):
    rsa = RSA(2048, e=3)
    rsa.generate_keys()

    return rsa.encrypt(message), rsa.N
示例#6
0
import sys
sys.setrecursionlimit(1500)
sys.path.insert(0, '../set_1_basics')
sys.path.insert(0, '../set_5_diffie_hellman_friends')
from utils import random_integer
from implement_rsa import RSA, modinv, rsa_string_to_integer, rsa_integer_to_string

ORACLE_KEY = RSA(2048, e=3)
ORACLE_KEY.generate_keys()

ORACLE_HISTORY = [] # prevent submission of the same ciphertext twice

def unpadded_message_oracle(ciphertext):
    if ciphertext in ORACLE_HISTORY:
        raise Exception('i have already seen this ciphertext')

    message = ORACLE_KEY.decrypt(ciphertext)
    ORACLE_HISTORY.append(ciphertext)

    return message

def exploit_oracle(ciphertext):
    n = ORACLE_KEY.N
    e = ORACLE_KEY.e

    s = random_integer(2, n-1)
    crafted_c = (pow(s, e, n) * ciphertext) % n

    crafted_p = unpadded_message_oracle(crafted_c)
    crafted_p = rsa_string_to_integer(crafted_p)
示例#7
0
import sys
sys.setrecursionlimit(1500)
sys.path.insert(0, '../set_1_basics')
sys.path.insert(0, '../set_5_diffie_hellman_friends')
from utils import random_integer, base64_to_bytearray
from implement_rsa import RSA, modinv, rsa_string_to_integer, rsa_integer_to_string
from decimal import *
from math import ceil, floor, log

ORACLE_KEY = RSA(1024, e=65537)
ORACLE_KEY.generate_keys()

def parity_oracle(ciphertext):
    plaintext_int = ORACLE_KEY.decrypt(ciphertext, encode=False)
    return plaintext_int % 2 == 0

def attack_parity_oracle(ciphertext, e, n):
    lb = Decimal(0)
    ub = Decimal(n)

    k = int(ceil(log(n, 2)))    # n. of iterations
    getcontext().prec = k       # allows for 'precise enough' floats

    c = ciphertext
    enctwo = pow(2, e, n)

    for i in xrange(1, k+1):
        c = (c * enctwo) % n
        nb = (lb + ub) / 2

        if parity_oracle(c):