예제 #1
0
class CryptoPan:
    def __init__(self, key):
        if len(key) != 32:
            raise CryptoPanError("Key must be a 32 byte long string")
        self.aes = AES(key[0:16])
        self.pad = self.aes.encrypt(key[16:32])
        f4bp = self.toint([ord(x) for x in self.pad[0:4]])
        self.masks = [(mask, f4bp & (~mask)) for mask in (0xFFFFFFFF >> (32 - p) << (32 - p) for p in range(0, 32))]

    def toint(self, array):
        return array[0] << 24 | array[1] << 16 | array[2] << 8 | array[3]

    def toarray(self, n):
        for i in range(3, -1, -1):
            yield (n >> (i * 8)) & 0xFF

    def anonymize(self, ip):
        result = 0
        address = [int(x) for x in ip.split(".")]
        if len(address) != 4:
            raise CryptoPanError("Invalid IPv4 Address")

        address = self.toint(address)

        def calc(a):
            """ calculate the first bit for Crypto-PAN"""
            inp = "".join((chr(x) for x in self.toarray(a))) + self.pad[4:]
            rin_output = self.aes.encrypt(inp)
            return ord(rin_output[0]) >> 7

        addresses = ((address & mask[0]) | mask[1] for mask in self.masks)
        result = reduce(lambda x, y: x << 1 | y, (calc(a) for a in addresses), 0)

        return ".".join(["%s" % x for x in self.toarray(result ^ address)])
예제 #2
0
def aes_key_wrap(key, p):
    """
    AES key wrap

    @type  key: bytes
    @param key: Key; length MUST be 16, 24, or 32 octets
    @type  p  : bytes
    @param p  : Plaintext; length MUST be a multiple of 8 octets
    @rtype: bytes
    @return: Wrapped version of plaintext
    """
    assert (len(p) % 8 == 0)

    n = len(p) / 8
    r = list(range(n + 1))
    r[0] = b'\0\0\0\0\0\0\0\0'
    for i in range(1, n + 1):
        r[i] = p[(i - 1) * 8:i * 8]
    a = b'\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6'

    aes = AESCipher(key)
    for j in range(0, 6):
        for i in range(1, n + 1):
            t = pack("!q", (n * j) + i)
            b = aes.encrypt(a + r[i])  # B = AES(K, A | R[i])
            a = strxor(b[:8], t)  # A = MSB(64, B) ^ t where t = (n*j)+i
            r[i] = b[8:]  # R[i] = LSB(64, B)

    r[0] = a
    return "".join(r)
예제 #3
0
    def encrypt(self):
        key = "@[email protected]"
        iv = chr(0) * 16
        aes = AESCipher(key, mode=MODE_ECB, IV=iv)
        fulltext = self.gcode.text
        padded = Padding.appendPadding(fulltext)
        enc_text = aes.encrypt(padded)

        magic = "3DPFNKG13WTW"
        magic2 = struct.pack("8B", 1, 2, 0, 0, 0, 0, 18, 76)
        blanks = chr(0) * 4684
        tag = "TagEJ256"
        magic3 = struct.pack("4B", 0, 0, 0, 68)
        crc32 = binascii.crc32(enc_text)
        crcstr = struct.pack(">l", crc32)
        encrypted_header = self.encrypt_header()
        bio = BytesIO()
        bio.write(magic)
        bio.write(magic2)
        bio.write(blanks)
        bio.write(tag)
        bio.write(magic3)
        bio.write(crcstr)
        bio.write((chr(0) * (68 - len(crcstr))))
        log.debug("Length of encrypted header: {}".format(
            len(encrypted_header)))
        if len(encrypted_header) > (8192 - bio.tell()):
            log.error("Header is too big to fit file format!")
        bio.write(encrypted_header)
        left = 8192 - bio.tell()
        bio.write((chr(0) * left))
        bio.write(enc_text)
        return bio.getvalue()
예제 #4
0
 def encrypt_header(self):
     key = "@xyzprinting.com"
     iv = chr(0) * 16
     aes = AESCipher(key, mode=MODE_CBC, IV=iv)
     text = self.gcode.header_text
     header = Padding.appendPadding(text)
     return aes.encrypt(header)
예제 #5
0
def apply_aes_ctr(key, nonce, source):
  cipher = AESCipher(key)
  dest = b""

  for (i, cipher_block) in generate_blocks(source, BLOCK_SIZE):
    pre_enc = add_bytestrings(nonce, int_to_bytes(i, BLOCK_SIZE))
    enc = cipher.encrypt(pre_enc)

    dest_block = xor_bytestrings(enc, cipher_block)
    dest += dest_block

  return dest
예제 #6
0
def aes_encrypt(msg, key=None):
    msg = _aes_pad(msg)

    global _aes
    if key is not None:
        _aes_local = AESCipher(key)
        ret = _aes_local.encrypt(msg)
    else:
        ret = _aes.encrypt(msg)

    ret = base64.b64encode(ret)
    return ret
예제 #7
0
def aes_encrypt(msg, key=None):
    msg = _aes_pad(msg)

    global _aes
    if key is not None:
        _aes_local = AESCipher(key)
        ret = _aes_local.encrypt(msg)
    else:
        ret = _aes.encrypt(msg)

    ret = base64.b64encode(ret)
    return ret
예제 #8
0
class CryptoPan():
    def __init__(self, key):
        if len(key) != 32:
            raise CryptoPanError("Key must be a 32 byte long string")
        self.aes = AES(key[0:16])
        self.pad = self.aes.encrypt(key[16:32])
        self.first4bytes_pad = self.toint([ord(x) for x in self.pad[0:4]])

    def toint(self, array):
        return array[0] << 24 | array[1] << 16 | array[2] << 8 | array[3]

    def toarray(self, n):
        for i in range(3, -1, -1):
            yield (n >> (i * 8)) & 0xFF

    def anonymize(self, ip):
        result = 0
        address = [int(x) for x in ip.split(".")]
        if len(address) != 4:
            raise CryptoPanError("Invalid IPv4 Address")

        address = self.toint(address)

        def calc(a):
            """ calculate the first bit for Crypto-PAN"""
            inp = "".join([chr(x) for x in self.toarray(a)]) + self.pad[4:]
            rin_output = self.aes.encrypt(inp)
            return ord(rin_output[0]) >> 7

        def prep_addr(p, address):
            """ prepare adress for calculation """
            mask = 0xFFFFFFFF >> (32 - p) << (32 - p)
            return (address & mask) | (self.first4bytes_pad & (~mask))

        addresses = [prep_addr(p, address) for p in range(0, 32)]
        result = reduce(lambda x, y: x << 1 | y, [calc(a) for a in addresses],
                        0)

        return ".".join(["%s" % x for x in self.toarray(result ^ address)])
예제 #9
0
def encrypt_aes_cbc(key, plaintext):
  padded_plaintext = pad_pkcs7(plaintext)

  cipher = AESCipher(key)
  iv = cryptorandom(BLOCK_SIZE)
  pre_xor = iv

  ciphertext = b""
  for (i, plaintext_block) in generate_blocks(padded_plaintext, BLOCK_SIZE):
    xord = xor_bytestrings(plaintext_block, pre_xor)

    cipher_block = cipher.encrypt(xord)
    ciphertext += cipher_block
    pre_xor = cipher_block

  return iv + ciphertext
예제 #10
0
def format_secret(session, secret, content_type):
    """Formats `secret` to make possible to pass it to the
	Secret Service API."""
    if not isinstance(secret, bytes):
        secret = secret.encode('utf-8')
    if not session.encrypted:
        return dbus.Struct(
            (session.object_path, '', dbus.ByteArray(secret), content_type))
    # PKCS-7 style padding
    padding = 0x10 - (len(secret) & 0xf)
    secret += bytes(bytearray((padding, )) * padding)
    aes_iv = long_to_bytes(getrandbits(0x80))
    # If shorter than 16 bytes, prepend zero bytes
    aes_iv = b'\x00' * (0x10 - len(aes_iv)) + aes_iv
    aes_cipher = AESCipher(session.aes_key, mode=MODE_CBC, IV=aes_iv)
    return dbus.Struct(
        (session.object_path, dbus.Array(aes_iv),
         dbus.Array(bytearray(aes_cipher.encrypt(secret))), content_type))
예제 #11
0
def format_secret(session, secret, content_type):
	"""Formats `secret` to make possible to pass it to the
	Secret Service API."""
	if not isinstance(secret, bytes):
		secret = secret.encode('utf-8')
	if not session.encrypted:
		return dbus.Struct((session.object_path, '',
			dbus.ByteArray(secret), content_type))
	# PKCS-7 style padding
	padding = 0x10 - (len(secret) & 0xf)
	secret += bytes(bytearray((padding,)) * padding)
	aes_iv = get_random_bytes(block_size)
	aes_cipher = AESCipher(session.aes_key, mode=MODE_CBC, IV=aes_iv)
	return dbus.Struct((
		session.object_path,
		dbus.Array(aes_iv),
		dbus.Array(bytearray(aes_cipher.encrypt(secret))),
		content_type
	))
예제 #12
0
 def aes_key_wrap(key, p):
     assert( len(p) % 8 == 0 )
     
     n = len(p)/8
     r = range(n+1)
     r[0] = b'\0\0\0\0\0\0\0\0'
     for i in range(1,n+1):
         r[i] = p[(i-1)*8:i*8]
     a = b'\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6'
 
     aes = AESCipher(key)
     for j in range(0,6):
         for i in range(1,n+1):
             t = struct.pack("!q", (n*j)+i)
             b = aes.encrypt(a+r[i])     # B = AES(K, A | R[i])
             a = strxor(b[:8], t)        # A = MSB(64, B) ^ t where t = (n*j)+i
             r[i] = b[8:]                # R[i] = LSB(64, B)
 
     r[0] = a
     return "".join(r)
예제 #13
0
    def aes_key_wrap(key, p):
        assert (len(p) % 8 == 0)

        n = len(p) / 8
        r = range(n + 1)
        r[0] = b'\0\0\0\0\0\0\0\0'
        for i in range(1, n + 1):
            r[i] = p[(i - 1) * 8:i * 8]
        a = b'\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6'

        aes = AESCipher(key)
        for j in range(0, 6):
            for i in range(1, n + 1):
                t = struct.pack("!q", (n * j) + i)
                b = aes.encrypt(a + r[i])  # B = AES(K, A | R[i])
                a = strxor(b[:8], t)  # A = MSB(64, B) ^ t where t = (n*j)+i
                r[i] = b[8:]  # R[i] = LSB(64, B)

        r[0] = a
        return "".join(r)
예제 #14
0
def encrypt(message: bytes, aes: AES.AESCipher) -> bytes:
    """Chiffre une chaine d'octets

    Chiffrement d'une chaine codée sur un multiple de 16 octets.
    Le chiffrement est effectué à l'aide de l'AES, fourni au préalable.
    La fonction retourne donc la chaine chiffrée.
    Un Zero Padding est appliqué.
    """

    # Convert eventual not-bytes object to bytes
    message = pickle.dumps(message)
    # Convert sequence of bytes to acii-compatible sequence of bytes
    message = binascii.hexlify(message)

    # Crypto.Cipher.AES.AESCipher needs an ASCII string to work on
    message_str = message.decode('ascii')

    # Section with zero-padding logic
    length = len(message_str)
    # Adding a position for the header value
    length += 1

    # Calculating length of needed padding
    if (length % 16) != 0:
        complement_size = 16 - (length % 16)
    else:
        complement_size = 0

    # Header holds the size of added padding
    header = hex(complement_size)
    # Stripping leading "0x" by keeping only last char
    header = header[-1]

    # Creating padding ASCII string with zeros
    complement = "0" * complement_size

    # Merging header message and padding
    message_str = "".join([header, message_str, complement])

    # Encrypt zero-padded message
    return aes.encrypt(message_str)
예제 #15
0
def format_secret(session, secret, content_type):
	"""Formats `secret` to make possible to pass it to the
	Secret Service API."""
	if not isinstance(secret, bytes):
		secret = secret.encode('utf-8')
	if not session.encrypted:
		return dbus.Struct((session.object_path, '',
			dbus.ByteArray(secret), content_type))
	# PKCS-7 style padding
	padding = 0x10 - (len(secret) & 0xf)
	secret += bytes(bytearray((padding,)) * padding)
	aes_iv = long_to_bytes(getrandbits(0x80))
	# If shorter than 16 bytes, prepend zero bytes
	aes_iv = b'\x00' * (0x10 - len(aes_iv)) + aes_iv
	aes_cipher = AESCipher(session.aes_key, mode=MODE_CBC, IV=aes_iv)
	return dbus.Struct((
		session.object_path,
		dbus.Array(aes_iv),
		dbus.Array(bytearray(aes_cipher.encrypt(secret))),
		content_type
	))
예제 #16
0
    def decrypt_AES128CCM(key, n, M, c, a):
        # Set parameters
        L = 15-len(n)  
        ln = len(n)
        la = len(a)
        lm = len(c) - M
        lblock = AES.block_size
        assert( L >= 2 and L <= 8 )
        assert( lm < (1<<(8*L)) )
        aes = AESCipher(key)

        # PART 1: Compute the key stream to get MAC value and authentication tag
        U = c[-M:]
        Lp = L-1
        Flags = struct.pack("B", Lp)
        i = 0
        A0 = Flags + n + struct.pack("!Q", 0)[-L:]
        S0 = aes.encrypt(A0)
        T = strxor(U, S0[:M])
        
        remaining = lm
        S = b''
        while remaining >= lblock:
            remaining -= lblock
            i += 1
            Ai = Flags + n + struct.pack("!Q", i)[-L:]
            Si = aes.encrypt(Ai)
            S = S + Si
        i += 1
        Aend = Flags + n + struct.pack("!Q", i)[-L:]
        Send = aes.encrypt(Aend)[:remaining]
        S = S + Send
        m = strxor(c[:-M], S)

        # PART 2: Compute the MAC to verify the authentication tag
        # Note: With no data, this is just AES-CBC with B0 as the IV
        Adata = 0
        if la > 0: 
            Adata = 1
        Mp = (M-2)/2
        Lp = L-1
        Flags = 64*Adata + 8*Mp + Lp
        B = struct.pack("B", Flags) + n + struct.pack("!Q", lm)[-L:]
        
        # If there is associated data, append it
        if la > 0:
            # Encode the length
            La = b''
            if (la < 2**16 - 2**8):
                La = struct.pack("!H", la)
            elif (la < 2**32):
                La = b'\xFF\xFE' + struct.pack("!I", la)
            elif (la < 2**64):
                La = b'\xFF\xFE' + struct.pack("!Q", la)
            lla = len(La)
            # Compute the amount of zero-padding we need
            lza = lblock - ((la + lla)%lblock)
            B = B + La + a + b'\0'*lza

        # Append the message
        lzm = lblock - (lm % lblock)
        B = B + m + b'\0'*lzm
        nB = len(B) / lblock

        # Compute the CBC-MAC
        X = aes.encrypt( B[:lblock] )
        for i in range(nB-1):
            X = strxor( X, B[ lblock*(i+1) : lblock*(i+2) ] )
            X = aes.encrypt(X)
        if T != X[:M]:
            raise Exception("Integrity check failed")

        return m
예제 #17
0
    def encrypt_AES128CCM(key, n, M, m, a):
        # Set parameters
        ln = len(n)
        lm = len(m)
        la = len(a)
        lblock = AES.block_size
        L = 15-len(n)  
        assert( L >= 2 and L <= 8 )
        assert( lm < (1<<(8*L)) )
        aes = AESCipher(key)

        # PART 1: Compute the authentication tag
        # Note: With no data, this is just AES-CBC with B0 as the IV
        Adata = 0
        if la > 0: 
            Adata = 1
        Mp = (M-2)/2
        Lp = L-1
        Flags = 64*Adata + 8*Mp + Lp
        B = struct.pack("B", Flags) + n + struct.pack("!Q", lm)[-L:]
        
        # If there is associated data, append it
        if la > 0:
            # Encode the length
            La = b''
            if (la < 2**16 - 2**8):
                La = struct.pack("!H", la)
            elif (la < 2**32):
                La = b'\xFF\xFE' + struct.pack("!I", la)
            elif (la < 2**64):
                La = b'\xFF\xFE' + struct.pack("!Q", la)
            lla = len(La)
            # Compute the amount of zero-padding we need
            lza = lblock - ((la + lla)%lblock)
            B = B + La + a + b'\0'*lza

        # Append the message
        lzm = lblock - (lm % lblock)
        B = B + m + b'\0'*lzm
        nB = len(B) / lblock

        # Compute the CBC-MAC
        X = aes.encrypt( B[:lblock] )
        for i in range(nB-1):
            X = strxor( X, B[ lblock*(i+1) : lblock*(i+2) ] )
            X = aes.encrypt(X)
        T = X[:M]

        # PART 2: Encrypt the message
        Flags = struct.pack("B", Lp)
        i=0
        A0 = Flags + n + struct.pack("!Q", i)[-L:]
        S0 = aes.encrypt(A0)
        U = strxor(T, S0[:M])
        
        remaining = lm
        S = b''
        while remaining >= lblock:
            remaining -= lblock
            i += 1
            Ai = Flags + n + struct.pack("!Q", i)[-L:]
            Si = aes.encrypt(Ai)
            S = S + Si
        i += 1
        Aend = Flags + n + struct.pack("!Q", i)[-L:]
        Send = aes.encrypt(Aend)[:remaining]
        S = S + Send
        c = strxor(m, S)

        return c+U
예제 #18
0
    def decrypt_AES128CCM(key, n, M, c, a):
        # Set parameters
        L = 15 - len(n)
        ln = len(n)
        la = len(a)
        lm = len(c) - M
        lblock = AES.block_size
        assert (L >= 2 and L <= 8)
        assert (lm < (1 << (8 * L)))
        aes = AESCipher(key)

        # PART 1: Compute the key stream to get MAC value and authentication tag
        U = c[-M:]
        Lp = L - 1
        Flags = struct.pack("B", Lp)
        i = 0
        A0 = Flags + n + struct.pack("!Q", 0)[-L:]
        S0 = aes.encrypt(A0)
        T = strxor(U, S0[:M])

        remaining = lm
        S = b''
        while remaining >= lblock:
            remaining -= lblock
            i += 1
            Ai = Flags + n + struct.pack("!Q", i)[-L:]
            Si = aes.encrypt(Ai)
            S = S + Si
        i += 1
        Aend = Flags + n + struct.pack("!Q", i)[-L:]
        Send = aes.encrypt(Aend)[:remaining]
        S = S + Send
        m = strxor(c[:-M], S)

        # PART 2: Compute the MAC to verify the authentication tag
        # Note: With no data, this is just AES-CBC with B0 as the IV
        Adata = 0
        if la > 0:
            Adata = 1
        Mp = (M - 2) / 2
        Lp = L - 1
        Flags = 64 * Adata + 8 * Mp + Lp
        B = struct.pack("B", Flags) + n + struct.pack("!Q", lm)[-L:]

        # If there is associated data, append it
        if la > 0:
            # Encode the length
            La = b''
            if (la < 2**16 - 2**8):
                La = struct.pack("!H", la)
            elif (la < 2**32):
                La = b'\xFF\xFE' + struct.pack("!I", la)
            elif (la < 2**64):
                La = b'\xFF\xFE' + struct.pack("!Q", la)
            lla = len(La)
            # Compute the amount of zero-padding we need
            lza = lblock - ((la + lla) % lblock)
            B = B + La + a + b'\0' * lza

        # Append the message
        lzm = lblock - (lm % lblock)
        B = B + m + b'\0' * lzm
        nB = len(B) / lblock

        # Compute the CBC-MAC
        X = aes.encrypt(B[:lblock])
        for i in range(nB - 1):
            X = strxor(X, B[lblock * (i + 1):lblock * (i + 2)])
            X = aes.encrypt(X)
        if T != X[:M]:
            raise Exception("Integrity check failed")

        return m
예제 #19
0
    def encrypt_AES128CCM(key, n, M, m, a):
        # Set parameters
        ln = len(n)
        lm = len(m)
        la = len(a)
        lblock = AES.block_size
        L = 15 - len(n)
        assert (L >= 2 and L <= 8)
        assert (lm < (1 << (8 * L)))
        assert (2 <= M and M <= 16 and M % 2 == 0)
        aes = AESCipher(key)

        # PART 1: Compute the authentication tag
        # Note: With no data, this is just AES-CBC with B0 as the IV
        Adata = 0
        if la > 0:
            Adata = 1
        Mp = (M - 2) / 2
        Lp = L - 1
        Flags = 64 * Adata + 8 * Mp + Lp
        B = struct.pack("B", Flags) + n + struct.pack("!Q", lm)[-L:]

        # If there is associated data, append it
        if la > 0:
            # Encode the length
            La = b''
            if (la < 2**16 - 2**8):
                La = struct.pack("!H", la)
            elif (la < 2**32):
                La = b'\xFF\xFE' + struct.pack("!I", la)
            elif (la < 2**64):
                La = b'\xFF\xFE' + struct.pack("!Q", la)
            lla = len(La)
            # Compute the amount of zero-padding we need
            lza = lblock - ((la + lla) % lblock)
            B = B + La + a + b'\0' * lza

        # Append the message
        lzm = lblock - (lm % lblock)
        B = B + m + b'\0' * lzm
        nB = len(B) / lblock

        # Compute the CBC-MAC
        X = aes.encrypt(B[:lblock])
        for i in range(nB - 1):
            X = strxor(X, B[lblock * (i + 1):lblock * (i + 2)])
            X = aes.encrypt(X)
        T = X[:M]

        # PART 2: Encrypt the message
        Flags = struct.pack("B", Lp)
        i = 0
        A0 = Flags + n + struct.pack("!Q", i)[-L:]
        S0 = aes.encrypt(A0)
        U = strxor(T, S0[:M])

        remaining = lm
        S = b''
        while remaining >= lblock:
            remaining -= lblock
            i += 1
            Ai = Flags + n + struct.pack("!Q", i)[-L:]
            Si = aes.encrypt(Ai)
            S = S + Si
        i += 1
        Aend = Flags + n + struct.pack("!Q", i)[-L:]
        Send = aes.encrypt(Aend)[:remaining]
        S = S + Send
        c = strxor(m, S)

        return c + U
예제 #20
0
def VotaHandler(request, ident, usuario=None):
    response = HttpResponse("", content_type='application/json', status=200)
    ans = {}
    ans['error'] = 0
    if request.method == 'GET':
        
        pg = request.GET.get('pg', None)
        enc = request.GET.get('enc', None)
        dec = request.GET.get('dec', None)
        if (pg is None):
            raise ParametrosIncompletosException()

        if (enc is not None):
            pas = darPassDePg(pg)
            ans['pas'] = pas 
            motor = AESCipher(pas)
            ans['ans'] = motor.encrypt(enc);
            response.write(simplejson.dumps(ans))
            return response
        elif (dec is not None):
            pas = darPassDePg(pg)
            ans['pas'] = pas 
            motor = AESCipher(pas)
            ans['ans'] = motor.decrypt(dec);
            response.write(simplejson.dumps(ans))
            return response
        
        usr = request.GET.get('u', None)
        vot = request.GET.get('v', None)
        if (usr is None or vot is None):
            raise ParametrosIncompletosException()
        
        consulta = [
                    'per.'+usr+'.humId',
                    'per.'+usr+'.nom',
                    'global.votacion',
                    ]
        
        datos = buscarTuplas(pg, consulta)
        datos = to_dict_simple(datos, None, True, ['id', 'i', 'd', 'sd'])
        
        
        if ((not ('global.votacion' in datos)) or datos['global.votacion'] is None):
            raise MalaPeticionException()
        rutaVotacion = datos['global.votacion']
        
        consulta = [
                    rutaVotacion+'.pregunta',
                    rutaVotacion+'.opciones.'+vot+'.txt',
                    ]
        
        datos2 = buscarTuplas(pg, consulta)
        datos2 = to_dict_simple(datos2, None, True, ['id', 'i', 'd', 'sd'])
        
        payloadModificacion = {"dat":{
                            rutaVotacion+'.resultado.u.'+usr: simplejson.dumps(vot)
                            },"acc":"+"}
        crearTuplas(pg, payloadModificacion)
        
        llave = ndb.Key('Pagina', comun.leerNumero(pg))
        unapagina = llave.get()
        
        publicar(unapagina.usr, unapagina.path, pg, payloadModificacion)
        
        ans['msg'] = datos2[rutaVotacion+'.pregunta']+' '+datos['per.'+usr+'.humId']+' vota por "'+datos2[rutaVotacion+'.opciones.'+vot+'.txt']+'"'
        #ans['msg1'] = datos
        #ans['msg2'] = datos2
        #ans['creacion'] = creacion

        response.write(simplejson.dumps(ans))
        return response