예제 #1
0
def prepare(message):
    """
    Suppose we intercept a padded ciphertext.
    Our goal is to completely decrypt it, just by using the oracle.
    """
    message_encoded = PKCS1_encode(message, k)
    ciphertext = rsa.encrypt_string(pk, message_encoded)
    return ciphertext
예제 #2
0
def run_tests(m):
    """
    Small sanity test suite
    """
    menc = PKCS1_encode(m, k)

    print("1. (un)pad:", PKCS1_decode(menc) == m)

    m1 = rsa.decrypt_string(sk, rsa.encrypt_string(pk, m))
    print("2. rsa w/o pad:", m == m1)

    m2 = PKCS1_decode(rsa.decrypt_string(sk, rsa.encrypt_string(pk, menc)))
    print("3. rsa w/ pad:", m == m2)

    m3 = oracle(rsa.encrypt_string(pk, menc)) == True
    print("4. oracle well-formed:", m3)

    m4 = oracle(rsa.encrypt_string(pk, m)) == False
    print("5. oracle not well-formed", m4)
예제 #3
0
    data in there, and I completely ignore the implementation of
    'other ASN.1 data'.
    """
    assert len(string) < 256
    assert bits % 8 == 0
    byte_goal = bits / 8
    prepend = "\x00\x01"
    append = "\x00ASN.1" + chr(len(string)) 
    bytes_to_add = (byte_goal -
                    (len(string) % byte_goal) -
                    len(prepend) -
                    len(append))
    return prepend + ("\xff" * bytes_to_add) + append + string

block = pkcs_1_5(hash, bits)
signature = rsa.encrypt_string(block, R) # Note: signing is w/ priv key.

def verify(sig, message, pubkey):
    block = rsa.decrypt_string(sig, pubkey)
    for i in range((bits/8) - len(block)):
        block = "\x00" + block
    return sha1(message).digest() == unpad(block)

def unpad(string):
    state = "start"
    result = ""
    for i, c in enumerate(string):
        if i == 0 and c != "\x00":
            return "FAIL " + str(i) + str([c]) + "_"
        elif i == 0:
            continue
예제 #4
0
    return (ciphertext * k**e) % n


def cleanup(string, substitution=''):
    safe = ''
    for c in string:
        if 32 <= ord(c) <= 126:
            safe += c
        else:
            safe += substitution
    return safe


b64s = 'VGhhdCdzIHdoeSBJIGZvdW5kIHlvdSBkb24ndCBwbGF5IGFyb3VuZCB3aXRoIHRoZSBGdW5reSBDb2xkIE1lZGluYQ=='
plaintext = base64.b64decode(b64s)
ciphertext = rsa.encrypt_string(plaintext, pubkey)
# um, if e=3, I don't think this string wraps the modulus. So in
# theory, I think we could just cube-root it, but oh well.

bounds = [0, n]
start = time.time()
for i in range(2048):
    p = parity(multiply(ciphertext, 2**(i + 1), e, n))
    half_the_dist = (bounds[1] - bounds[0]) / 2
    if p == 0:
        bounds = [bounds[0], bounds[1] - half_the_dist]
    elif p == 1:
        bounds = [bounds[0] + half_the_dist, bounds[1]]
    if i % 16 == 0:
        print p, i, cleanup(rsa.i2s(bounds[1]),
                            '_')  # get 256 char wide screen
예제 #5
0
def multiply(ciphertext, k, e, n):
    return (ciphertext * k ** e) % n

def cleanup(string, substitution=''):
    safe = ''
    for c in string:
        if 32 <= ord(c) <= 126:
            safe += c
        else:
            safe += substitution
    return safe

b64s = 'VGhhdCdzIHdoeSBJIGZvdW5kIHlvdSBkb24ndCBwbGF5IGFyb3VuZCB3aXRoIHRoZSBGdW5reSBDb2xkIE1lZGluYQ=='
plaintext = base64.b64decode(b64s)
ciphertext = rsa.encrypt_string(plaintext, pubkey)
# um, if e=3, I don't think this string wraps the modulus. So in
# theory, I think we could just cube-root it, but oh well.

bounds = [0, n]
start = time.time()
for i in range(2048):
    p = parity(multiply(ciphertext, 2**(i+1), e, n))
    half_the_dist = (bounds[1] - bounds[0]) / 2
    if p == 0:
        bounds = [bounds[0], bounds[1] -  half_the_dist]
    elif p == 1:
        bounds = [bounds[0] + half_the_dist, bounds[1]]
    if i % 16 == 0:
        print p, i, cleanup(rsa.i2s(bounds[1]), '_') # get 256 char wide screen
예제 #6
0
#     the file 'LICENSE' in the same directory as this file.

from cryptopals import warn, cuberoot
import rsa
import copy

k = 3  # How many times to encrypt the same plaintext, under different
# public keys.

message = 'Hello, world! I am gonna encrypt this thrice; uh oh.'
bits = len(message) * 8 / 2
c = [None] * k
n = [None] * k
for i in range(k):
    U, R = rsa.keypair(bits)
    ciphertext = rsa.encrypt_string(message, U)
    c[i] = ciphertext
    n[i] = U[1]  # the second part of the pubkey
    print "public     " + str(U[1])[:60] + "...."
    print "ciphertext " + str(ciphertext)[:60] + "...."

decrypt = rsa.decrypt_string(ciphertext, R)
print
print "Bob gets this message:", decrypt

#### Eve

# Calculate products of the moduli (pubkeys) EXCEPT pubkey number i.
ms = [None] * k
for i in range(k):
    x = copy.copy(n)
예제 #7
0
#     the file 'LICENSE' in the same directory as this file.

from cryptopals import warn, cuberoot
import rsa
import copy

k = 3 # How many times to encrypt the same plaintext, under different
      # public keys.

message = 'Hello, world! I am gonna encrypt this thrice; uh oh.'
bits = len(message) * 8 / 2
c = [None]*k
n = [None]*k
for i in range(k):
    U, R = rsa.keypair(bits)
    ciphertext = rsa.encrypt_string(message, U)
    c[i] = ciphertext
    n[i] = U[1] # the second part of the pubkey
    print "public     " + str(U[1])[:60] + "...."
    print "ciphertext " + str(ciphertext)[:60] + "...."

decrypt = rsa.decrypt_string(ciphertext, R)
print
print "Bob gets this message:", decrypt

#### Eve

# Calculate products of the moduli (pubkeys) EXCEPT pubkey number i.
ms = [None]*k
for i in range(k):
    x = copy.copy(n)
예제 #8
0
 def encrypt(self, message):
     result = {}
     result["ciphertext"] = rsa.encrypt_string(message, self.pub)
     result["pubkey"] = self.pub
     return result
예제 #9
0
    plaintext = rsa.decrypt_string(ciphertext, privkey)
    assert bits % 8 == 0
    bytes = bits / 8
    diff = bytes - len(plaintext)
    plaintext = "\x00" * diff + plaintext
    assert len(plaintext) == bytes, len(plaintext)
    return plaintext[0] == "\x00" and plaintext[1] == "\x02"

Bits = 768 / 2
pubkey, privkey = rsa.keypair(Bits)
print pubkey[1].bit_length(), "bit modulus"
short_message = """Now these points of data make a beautiful line
And we're out of beta; we're releasing on time"""

m = pkcs_1(short_message, Bits * 2) # Bits*2 = length of n
c = rsa.encrypt_string(m, pubkey)
print "Oracle says that raw ciphertext conforms?", oracle(c, privkey, Bits * 2)
assert oracle(c, privkey, Bits*2)

#### Step 1 (Easy if c is already PKCS conforming)
e = pubkey[0]
n = pubkey[1]
k = Bits * 2 / 8 # Length of n in bytes
B = 2 ** (8 * (k - 2))
s = [1]
c = [c]
M = [[[2*B, 3*B-1]]] # M is a list of sets of intervals.
i = 1

start = time()
while(1):
예제 #10
0
#!/usr/bin/env python

#     chal39.py - Implement RSA
#
#     Copyright (C) 2015 Andrew J. Zimolzak <*****@*****.**>,
#     and licensed under GNU GPL version 3. Full notice is found in
#     the file 'LICENSE' in the same directory as this file.

from cryptopals import warn
import rsa

hello = "Hello, world! This is a message from me to you! I am typing this on a certain type of computer, and I wonder how many bits I will need."

bits = len(hello) * 8 / 2
print bits, "bit key"
U, R = rsa.keypair(bits)
ciphertext = rsa.encrypt_string(hello, U)
decrypt = rsa.decrypt_string(ciphertext, R)
print "Decrypted this message:", decrypt
assert hello == decrypt

#### tests ####

warn("Passed assertions:", __file__)
예제 #11
0
 def encrypt(self, message):
     result = {}
     result['ciphertext'] = rsa.encrypt_string(message, self.pub)
     result['pubkey'] = self.pub
     return result
예제 #12
0
#!/usr/bin/env python

#     chal39.py - Implement RSA
#
#     Copyright (C) 2015 Andrew J. Zimolzak <*****@*****.**>,
#     and licensed under GNU GPL version 3. Full notice is found in
#     the file 'LICENSE' in the same directory as this file.

from cryptopals import warn
import rsa

hello = 'Hello, world! This is a message from me to you! I am typing this on a certain type of computer, and I wonder how many bits I will need.'

bits = len(hello) * 8 / 2
print bits, "bit key"
U, R = rsa.keypair(bits)
ciphertext = rsa.encrypt_string(hello, U)
decrypt = rsa.decrypt_string(ciphertext, R)
print "Decrypted this message:", decrypt
assert hello == decrypt

#### tests ####

warn("Passed assertions:", __file__)