示例#1
0
    def download_helper1(self, name, stored_root, file_id, encryption_key, mac_key):
        ret_mac = self.storage_server.get(file_id +self.crypto.cryptographic_hash("mac", 'SHA256'))

        if ret_mac is None:
            return None
        mac_text = ret_mac[:64]
        if self.crypto.message_authentication_code(stored_root, mac_key, 'SHA256') != mac_text:
            raise IntegrityError()
        downlength = int(ret_mac[64:])
        self.cipher_text_list[name] = []
        for i in range(0, downlength):
            self.cipher_text_list[name].append(self.storage_server.get(file_id + str(i)))

        hash_list = []
        for elem in self.cipher_text_list[name]:
            hash_list.append(self.crypto.cryptographic_hash(elem, 'SHA256'))
        new_temp_tree = MerkleTree(hash_list,self, name)
        new_temp_tree.pre_build()
        if new_temp_tree.root.val != stored_root:
            raise IntegrityError()
        plain_text_list = []
        for elem in self.cipher_text_list[name]:
            IV = elem[:16]
            plain_text_list.append(self.crypto.symmetric_decrypt(elem[16:], encryption_key, 'AES', 'CBC',IV+IV ,None, None,None, 128))
        self.stored_file[name] = ''.join(plain_text_list)
        return self.stored_file[name]
示例#2
0
    def read_verify_ptr(self, location, mac_key, decode_key):
        """
        goes to location, reads and verifies the pointer there
        returns the location of the associated headerfile, and the username of the file owner
        """
        raw = self.storage_server.get(location)
        if raw is None:
            return None, None

        mac_val = self.crypto.message_authentication_code(raw[MAC_LEN:],
                                                          mac_key,
                                                          hash_name='SHA256')
        flag = (mac_val == raw[:MAC_LEN])
        if not flag:
            raise IntegrityError("pointer mac invalid")

        nonce = raw[MAC_LEN:MAC_LEN + NONCE_LEN]
        counter = self.crypto.new_counter(COUNTER_LEN, prefix=nonce)
        message = self.crypto.symmetric_decrypt(raw[MAC_LEN + NONCE_LEN:],
                                                decode_key,
                                                cipher_name='AES',
                                                mode_name='CTR',
                                                counter=counter)
        if not message[:3] == 'PTR':
            raise IntegrityError(
                "Value at this location is not actually pointer.")

        return message[3:LOC_LEN + 3], message[
            LOC_LEN +
            3:]  # location, username of owner of file who controls this header block
示例#3
0
    def read_verify_header(self,
                           location,
                           mac_key,
                           decode_key,
                           include_metadata=False):
        """
        goes to location, reads and verifies the header file there
        returns the location, decryption key, and mac key required to read/write the actual file if not chained
        else returns the location, username of the owner who controls next header, None

        if include_metadata, contains list of people shared with
        """

        raw = self.storage_server.get(location)
        if raw is None:
            raise IntegrityError("header does not exist")

        mac_val = self.crypto.message_authentication_code(raw[MAC_LEN:],
                                                          mac_key,
                                                          hash_name='SHA256')
        flag = (mac_val == raw[:MAC_LEN])
        if not flag:
            raise IntegrityError("header mac invalid")

        nonce = raw[MAC_LEN:MAC_LEN + NONCE_LEN]
        counter = self.crypto.new_counter(COUNTER_LEN, prefix=nonce)

        message = self.crypto.symmetric_decrypt(raw[MAC_LEN + NONCE_LEN:],
                                                decode_key,
                                                cipher_name='AES',
                                                mode_name='CTR',
                                                counter=counter)

        if not message[:3] == 'HDR' and not message[:3] == 'MET':
            raise IntegrityError(
                "Value at this location is not actually header.")

        if include_metadata:
            if not message[:3] == 'MET':
                return message[3:LOC_LEN + 3], None, None, None
            else:
                if not message[LOC_LEN + 3:LOC_LEN + 4] == '0':
                    raise IntegrityError("Metatdata block is chained!" +
                                         message[LOC_LEN + 3:LOC_LEN + 4])
                return message[3:LOC_LEN + 3], message[
                    LOC_LEN + 4:LOC_LEN + ENC_KEY_LEN +
                    4], message[LOC_LEN + ENC_KEY_LEN + 4:LOC_LEN +
                                ENC_KEY_LEN + MAC_KEY_LEN +
                                4], message[LOC_LEN + ENC_KEY_LEN +
                                            MAC_KEY_LEN + 4:]
        else:
            if message[LOC_LEN + 3:LOC_LEN + 4] == '1':  # chained
                return message[3:LOC_LEN + 3], message[LOC_LEN + 4:], None
            else:
                return message[3:LOC_LEN +
                               3], message[LOC_LEN + 4:LOC_LEN + ENC_KEY_LEN +
                                           4], message[LOC_LEN + ENC_KEY_LEN +
                                                       4:LOC_LEN +
                                                       ENC_KEY_LEN +
                                                       MAC_KEY_LEN + 4]
示例#4
0
文件: client.py 项目: M777A2/crypto
    def sym_unpack(self, ct, sk_m, sk_s, filename):
        """
        symmetrically decrypts and verifies a ciphertext string
        :param ct: ciphertext to be unpacked
        :param sk_m: symmetric key for encrypting
        :param sk_s: symmetric key for signing
        :param str filename: the correct filename to avoid swap attacks

        :return: the plaintext
        :rtype: str
        """
        if not ct:
            return None
        sign = ct[-64:]  # get signature from end of msg CT
        resp = ct[:-64]  # remove signature from msg CT
        if self.crypto.message_authentication_code(
                resp + self.hash(filename), sk_s, "SHA256") != sign:  # verify
            raise IntegrityError("Bad Signature")
        try:
            iv = resp[-32:]  # save the IV at the end of the message CT
            resp = resp[:(-32)]  # remove IV from message CT
            resp = self.crypto.symmetric_decrypt(resp, sk_m, "AES", "CBC",
                                                 iv)  # decrypt msg w/AES-CBC
        except:  # any exception should be due to bit flipping by malicious server.
            raise IntegrityError("Data Corrupt")
        return resp
示例#5
0
文件: client.py 项目: M777A2/crypto
    def asym_unpack(self, ct, filename, sender=None):
        """unpack a symmetric key that has been stored on the insecure server

            :param str ct: The key to unpack.
            :param str sender: user who's public key is used to verify
            :param str filename: the correct filename to avoid swap attacks

            :returns: the symmetric key
            :rtype: str

            :raises IntegrityError: if the signature is invalid
        """
        if not ct:
            return None
        if not sender:
            sender = self.username
        # verify the key is valid
        signed, check = ct[:512], ct[512:] + self.hash(sender +
                                                       filename) + "ct"
        if self.crypto.asymmetric_verify(check, signed,
                                         self.pks.get_signature_key(sender)):
            ct = ct[512:]  # if valid, extract the cipher text
            try:
                pt = self.crypto.asymmetric_decrypt(
                    ct, self.elg_priv_key)  # decrypt
            except:
                raise IntegrityError("decryption failure")
        else:
            raise IntegrityError("Bad Signature")
        return pt
示例#6
0
文件: client.py 项目: M777A2/crypto
    def share(self, user, name):
        """
        create a new entry on your key_list file and add the user you intend to share with, then
        create a signed message which will let them find your pointer, and access their entry on
        the key_list file with a symmetric key.


        :param user: Who you are sharing with
        :param name: the file you plan to share

        :return: message, which will be sent to 'user'
        :rtype: str
        """
        uid = self.hash(path_join(self.username,
                                  name))  # join username and file name
        uid = self.crypto.message_authentication_code(
            uid, self.sk_n, "SHA256")  # use HMAC to hash/salt

        # open the pointer
        pointer = self.storage_server.get(uid)
        pointer = pointer[10:]  # remove [POINTER] tag
        signature = pointer[-512:]  # remove signature
        key_list = pointer[:-512]  # remove key_list

        if not self.crypto.asymmetric_verify(
                key_list + self.username, signature,
                self.pks.get_signature_key(self.username)):
            raise IntegrityError("bad key_list signature")
        key_list = json.loads(key_list)  # Load the dictionary with names

        # Get the info for the Data/Pointer that this pointer is aimed at
        try:
            pointer = key_list[self.hash2(self.username, self.sk_n2)]
            pointer = [self.asym_unpack(p, uid) for p in pointer]
        except KeyError:
            raise IntegrityError("own key entry missing")

        # make the new pointer
        sk_m = self.crypto.get_random_bytes(
            32)  # generate a symmetric key for the message
        sk_s = self.crypto.get_random_bytes(32)  # key for signing
        sk_n2 = pointer[
            4]  # key for HMAC of name (shared for the whole pointer)
        pointer = [self.sym_pack(p, sk_m, sk_s, uid) for p in pointer]
        owner_access = [self.asym_pack(sk_m, uid),
                        self.asym_pack(sk_s, uid)
                        ]  # let owner remember keys for revocation
        pointer += owner_access  # append the owner's keys to the back of the pointer
        key_list[self.hash2(user, sk_n2)] = pointer
        key_list = json.dumps(key_list)
        signature = self.crypto.asymmetric_sign(
            key_list + self.username,
            self.rsa_priv_key)  # sign key_list as owner
        key_list += signature
        key_list = "[POINTER] " + key_list
        self.storage_server.put(uid, key_list)
        msg = [uid, sk_m, sk_s, sk_n2]
        msg = [self.asym_pack(ms, "msg", user) for ms in msg]
        msg = json.dumps(msg)
        return msg
示例#7
0
    def receive_share(self, from_username, newname, message):
        # Replace with your implementation (not needed for Part 1)
        try:
            encrypted_keys_filename_string, signed_encrypted_keys_filename_string = util.from_json_string(
                message)
        except:
            raise IntegrityError()

        if self.crypto.asymmetric_verify(
                encrypted_keys_filename_string,
                signed_encrypted_keys_filename_string,
                self.pks.get_public_key(from_username)):
            decrypted_keys_filename_string = self.crypto.asymmetric_decrypt(
                encrypted_keys_filename_string, self.private_key)
            ka, ke, encrypted_original_filename = util.from_json_string(
                decrypted_keys_filename_string)

            k = self.get_unique_symmetric_key()
            encrypted_newfilename = self.crypto.message_authentication_code(
                newname, k, "MD5")
            half = int(len(encrypted_newfilename) / 4)
            encrypted_newfilename = encrypted_newfilename[:half]
            fid = path_join(self.username, encrypted_newfilename, "keys")
            keys_link = path_join(self.username, encrypted_original_filename,
                                  "keys")
            self.re_sign_keys(keys_link, from_username)
            self.storage_server.put(fid, "[POINTER] " + keys_link)

            uid = path_join(self.username, encrypted_newfilename)
            link = path_join(self.username, encrypted_original_filename)
            self.storage_server.put(uid, "[POINTER] " + link)
        else:
            raise IntegrityError()
示例#8
0
    def server_data(self, node, uid, ke, km):
        data = ""

        tree = LocalMerkleTree(self.hash, uid)
        tree.hash = node["h"]
        tree.left = node["l"]
        tree.right = node["r"]
        tree.length = node["n"]

        if node["r"] is None:
            data = self.get_server_node(node["l"], ke, km, isData=True)

            if self.hash(data) != node["h"]:
                raise IntegrityError()

            tree.left = DataNote(data, self.hash)
            tree.left.uid = node["l"]
            return data, tree
        else:
            left_node = self.get_server_node(node["l"], ke, km, isData=False)
            right_node = self.get_server_node(node["r"], ke, km, isData=False)

            if self.hash("{0}{1}".format(left_node["h"],
                                         right_node["h"])) != node["h"]:
                raise IntegrityError()

            tmp, tree.left = self.server_data(left_node, node["l"], ke, km)
            data += tmp

            tmp, tree.right = self.server_data(right_node, node["r"], ke, km)
            data += tmp

            return data, tree
示例#9
0
 def get_server_node(self, uid, ke, km, isData=False):
     res = self.resolve(uid, ke, km)
     if res is None: raise IntegrityError()
     _, _, _, server_root = res
     if not self.is_data_node(server_root): raise IntegrityError()
     if isData:
         return self.parse_data_node(server_root)
     else:
         return json.loads(self.parse_data_node(server_root))
示例#10
0
    def __init__(self, storage_server, public_key_server, crypto_object,
                 username):
        super().__init__(storage_server, public_key_server, crypto_object,
                         username)
        helper = self.string_concat(self.username, 'hello_world')
        uid = self.crypto.cryptographic_hash(helper, 'SHA256')
        helper2 = self.string_concat(self.username, 'dictionary')
        uid2 = self.crypto.cryptographic_hash(helper2, 'SHA256')
        if self.storage_server.get(uid) is None:
            #have no dictionary yet, and has no key for that dictionary yet
            self.dictionary = {}
            input_string = json.dumps(self.dictionary)
            God_key = self.crypto.get_random_bytes(16)
            encrypted_God_key= self.crypto.asymmetric_encrypt(God_key, self.pks.get_encryption_key(self.username))

            signed_God_key = self.crypto.asymmetric_sign(encrypted_God_key, self.rsa_priv_key)
            self.storage_server.put(uid, signed_God_key+encrypted_God_key)
            #let encrypt the dictionary now
            IV = self.crypto.get_random_bytes(16)
            encry_dictionary =IV+ self.crypto.symmetric_encrypt(input_string, self.crypto.cryptographic_hash(God_key,'SHA256'), 'AES','CBC', IV, None,self.crypto.new_counter(128),None, 128)
            encry_dictionary_mac = self.crypto.message_authentication_code(encry_dictionary, self.crypto.cryptographic_hash(God_key+ "Dictionary_mac", 'SHA256'), 'SHA256')
            self.storage_server.put(uid2, encry_dictionary_mac+encry_dictionary)
     
        else:
            #To get the storage key
            total_key = self.storage_server.get(uid)
            signed_God_key = total_key[:512]
            encrypted_God_key = total_key[512:]
            if not self.crypto.asymmetric_verify(encrypted_God_key, signed_God_key, self.pks.get_signature_key(self.username)):
                raise IntegrityError()
            God_key = self.crypto.asymmetric_decrypt(encrypted_God_key, self.elg_priv_key)
            #Stoarge key obtained

            if self.storage_server.get(uid2) is None:
                dictionary = {}
                self.dictionary = dictionary
                input_string = json.dumps(dictionary)
                IV = self.crypto.get_random_bytes(16)
                encry_dictionary = IV + self.crypto.symmetric_encrypt(input_string, self.crypto.cryptographic_hash(God_key, 'SHA256'), 'AES','CBC',IV, None,self.crypto.new_counter(128),None, 128)
                encry_dictionary_mac = self.crypto.message_authentication_code(encry_dictionary, self.crypto.cryptographic_hash(God_key+ "Dictionary_mac"), 'SHA256')
                self.storage_server.put(uid2, encry_dictionary_mac+encry_dictionary)
            else:
                total_dictionary = self.storage_server.get(uid2)
                encry_dictionary_mac = total_dictionary[:64]
                encry_dictionary = total_dictionary[64:]
                IV = encry_dictionary[:32]
                if self.crypto.message_authentication_code(encry_dictionary,self.crypto.cryptographic_hash(God_key+ "Dictionary_mac",'SHA256'),'SHA256') !=encry_dictionary_mac :
                    raise IntegrityError()
                input_string = self.crypto.symmetric_decrypt(encry_dictionary[32:],self.crypto.cryptographic_hash(God_key,'SHA256'), 'AES','CBC',IV, None,self.crypto.new_counter(128),None, 128)
                dictionary = json.loads(input_string)
                self.dictionary = dictionary
        #need a sharing key dictionary
        #meaning we are not store anything when we init
        self.stored_file = {}
        self.cipher_text_list = {}
        self.shared_dictionary= {}
示例#11
0
 def parse_pointer_node(self, value):
     assert self.is_pointer_node(
         value), "must be a data node for parse_share_node"
     prefix = "[POINTER]"
     value = value[len(prefix):]
     if "||" not in value: raise IntegrityError()
     parsed = value.split("||")
     if len(parsed) != 3: raise IntegrityError()
     ke, km, did = parsed
     return ke, km, did
示例#12
0
    def download(self, name):
        # Replace with your implementation
        ka, ke = self.get_file_keys(name)
        k = self.get_unique_symmetric_key()
        cipher_name = self.crypto.message_authentication_code(name, k, "MD5")
        half = int(len(cipher_name) / 4)
        cipher_name = cipher_name[:half]
        uid = self.revolve(path_join(self.username, cipher_name))
        res = self.storage_server.get(uid)

        if not res:
            return None
        else:
            cipher_all_string = res[7:]
            try:
                IV, cipher_value, old_tag = util.from_json_string(
                    cipher_all_string)
            except:
                raise IntegrityError()

            new_tag = self.crypto.message_authentication_code(
                IV + cipher_value + uid, ka, "MD5")

            if old_tag != new_tag:
                raise IntegrityError()
            else:
                chunk_num_string = self.crypto.symmetric_decrypt(
                    cipher_value, ke, "AES", "CBC", IV)
                chunk_num = int(chunk_num_string)

        value = ""
        for i in range(chunk_num):
            uid_i = path_join(uid, str(i))
            res = self.storage_server.get(uid_i)

            if not res:
                return None
            else:
                cipher_all_string = res[7:]
                try:
                    IV, cipher_value, old_tag = util.from_json_string(
                        cipher_all_string)
                except:
                    raise IntegrityError()

                new_tag = self.crypto.message_authentication_code(
                    IV + cipher_value + uid_i, ka, "MD5")

                if old_tag != new_tag:
                    raise IntegrityError()
                else:
                    value += self.crypto.symmetric_decrypt(
                        cipher_value, ke, "AES", "CBC", IV)

        return value
示例#13
0
    def receive_share(self, from_username, newname, message):
        sender_pub_key = self.pks.get_public_key(from_username)

        try:
            output = util.from_json_string(message)
            crypted, sign = output
        except:
            raise IntegrityError()

        # DECRYPT RECEIVED MESSAGE
        if self.crypto.asymmetric_verify(crypted, sign, sender_pub_key):
            msg = self.crypto.asymmetric_decrypt(crypted, self.private_key)
            msg = util.from_json_string(msg)

            session_key = msg['session_key']
            file_id = msg['file_id']
        else:
            raise IntegrityError()

        # GET DIRECTORY KEYS
        directory_keys = self.get_directory_keys()
        sym_ke, sym_ka = directory_keys

        # GET DIRECTORY
        client_ID = path_join(self.username, "directory")
        resp = self.storage_server.get(client_ID)
        if resp is None:
            directory = {
                newname: {
                    "keys": session_key,
                    "shared": [],
                    "file_id": file_id
                }
            }
        else:
            directory = self.decrypt_directory(resp, sym_ke, sym_ka)
            directory[newname] = {
                "keys": session_key,
                "shared": [],
                "file_id": file_id
            }

        # can cache directory here
        self.directory[newname] = {
            "keys": session_key,
            "shared": [],
            "file_id": file_id
        }

        self.encrypt_directory(client_ID, directory, sym_ke, sym_ka)
示例#14
0
文件: client.py 项目: M777A2/crypto
    def resolve(self, uid):
        """
        navigates through and unpacks a series of linked pointers until it reaches a [DATA] file.

        :param uid: starting location

        :return uid: The location of the [DATA] file
        :return sk_m: the decryption , symmetric key
        :return sk_s: the signature symmetric key
        :rtype str, str, str
        """
        sk_n2 = self.sk_n2
        sk_m = None
        sk_s = None
        sk_t = None
        owner = self.username
        requester = self.username
        while True:
            res = self.storage_server.get(uid)
            if res is None or res.startswith("[DATA]"):
                return uid, sk_m, sk_s, sk_t
            elif res.startswith("[POINTER]"):
                pointer = res[10:]  # remove [POINTER] tag
                signature = pointer[-512:]
                key_list = pointer[:-512]
                if not self.crypto.asymmetric_verify(
                        key_list + owner, signature,
                        self.pks.get_signature_key(owner)):
                    raise IntegrityError("bad key_list verification")
                key_list = json.loads(
                    key_list)  # Load the dictionary with names
                try:
                    pointer = key_list[self.hash2(
                        requester, sk_n2)]  # go to your place in dictionary
                    if sk_m and sk_s:  # if you have symmetric keys, you are following the chain'
                        for i in range(6):
                            pointer[i] = self.sym_unpack(
                                pointer[i], sk_m, sk_s, uid)
                    else:  # if you do not have symmetric keys, you should own this pointer.
                        pointer = [self.asym_unpack(p, uid) for p in pointer]
                except KeyError:
                    self.storage_server.put("invalid", "restricted")
                    return "invalid", None, None, None
                requester = owner  # you are now requesting as the owner of the last pointer
                uid, sk_m, sk_s, owner, sk_n2, sk_t = pointer[:
                                                              6]  # update the location, keys and who owns the pointer
            else:
                raise IntegrityError()
示例#15
0
    def __init__(self, storage_server, public_key_server, crypto_object,
                 username):
        super().__init__(storage_server, public_key_server, crypto_object,
                         username)
        location = username + "my key"

        self.key = self.storage_server.get(location)

        if not self.key:
            self.key = self.crypto.get_random_bytes(32)

            encrypted_key = self.crypto.asymmetric_encrypt(
                self.key, self.pks.get_encryption_key(self.username))
            encrypted_key += self.crypto.asymmetric_sign(
                encrypted_key, self.rsa_priv_key)

            self.storage_server.put(location, encrypted_key)
        else:
            sign = self.key[-512:]
            self.key = self.key[:-512]
            if self.crypto.asymmetric_verify(
                    self.key, sign, self.pks.get_signature_key(self.username)):
                self.key = self.crypto.asymmetric_decrypt(
                    self.key, self.elg_priv_key)
            else:
                print("Verification error")
                raise IntegrityError()
示例#16
0
    def check_integrity_and_get_value(self, ka, data_id):
        all_value_string = self.storage_server.get(data_id)
        if not all_value_string:
            return None
        else:
            try:
                value_string, MACed_value_string = util.from_json_string(
                    all_value_string[7:])
            except:
                raise IntegrityError()

            if self.crypto.message_authentication_code(
                    value_string, ka, "MD5") == MACed_value_string:
                return value_string
            else:
                raise IntegrityError()
示例#17
0
    def create_header(self, file_loc, arg1, arg2, chain=False, metadata=False):
        header_location = self.crypto.get_random_bytes(LOC_LEN)[:LOC_LEN]  #idk
        if chain:
            if metadata:
                raise IntegrityError("can't create chinaed metadata block!")
            #TODO for sharing
            value = 'HDR' + file_loc + "1" + arg1 + arg2
        else:
            if metadata:
                value = 'MET' + file_loc + "0" + arg1 + arg2
            else:
                value = 'HDR' + file_loc + "0" + arg1 + arg2

        aes_key = str(self.pks.get_encryption_key(
            self.username).y)[:ENC_KEY_LEN]
        mac_key = str(self.pks.get_encryption_key(
            self.username).y)[:ENC_KEY_LEN]

        nonce = self.crypto.get_random_bytes(NONCE_LEN // 2)
        counter = self.crypto.new_counter(COUNTER_LEN, prefix=nonce)
        aes_val = self.crypto.symmetric_encrypt(value,
                                                aes_key,
                                                cipher_name='AES',
                                                mode_name='CTR',
                                                counter=counter)
        mac_val = self.crypto.message_authentication_code(nonce + aes_val,
                                                          mac_key,
                                                          hash_name='SHA256')

        self.storage_server.put(header_location, mac_val + nonce + aes_val)
        return header_location
示例#18
0
    def share(self, user, name):
        SYMMETRIC_KEY_LENGTH = 16

        # Get symmetric keys
        ke, km, kn = self.get_symmetric_keys()
        # Get shares directory
        shares = self.get_shares_directory()
        # Get ID for the key node of file NAME
        uid = self.get_kid(name, kn)
        # Get ke, km, uid that NAME links to for this client
        node = self.decrypt_values_at_id(uid, ke, km)
        if self.is_pointer_node(node):
            ke, km, uid = self.parse_pointer_node(node)
        elif not self.is_data_node(node):
            raise IntegrityError()
        # Create value stored at share node
        share_node_v = "[POINTER]{0}||{1}||{2}".format(ke, km, uid)
        # New key to encrypt share node
        ke2, km2, _ = self.new_symmetric_keys()
        # New share node of id DID
        did = self.new_did()
        # Encrypt share node with new keys
        share_node_v = self.encrypt_value_for_storage(did, share_node_v, ke2,
                                                      km2)
        # Store share node at a random new data node id: did
        self.storage_server.put(did, share_node_v)

        # Construct the message to share
        msg = "[POINTER]{0}||{1}||{2}".format(ke2, km2, did)
        encrypt_k = self.pks.get_encryption_key(user)
        if encrypt_k is None: raise IntegrityError()
        ciphertext = self.crypto.asymmetric_encrypt(msg, encrypt_k)
        ciphertext_user = path_join([ciphertext, user], separator="/")
        # Sign the encryption
        sig = self.crypto.asymmetric_sign(ciphertext_user, self.rsa_priv_key)

        # Update information about shared node to the directory
        if name not in shares: shares[name] = dict()

        shares[name][user] = {"did": did, "ke": ke2, "km": km2}

        # Update shares directory
        self.put_shares_directory(shares)

        # Return the share message
        return path_join([ciphertext, sig], separator="||")
示例#19
0
    def get_file_keys(self, name):
        k = self.get_unique_symmetric_key()
        encrypted_filename = self.crypto.message_authentication_code(
            name, k, "MD5")
        half = int(len(encrypted_filename) / 4)
        encrypted_filename = encrypted_filename[:half]
        fid = self.revolve(path_join(self.username, encrypted_filename,
                                     "keys"))
        fkeys = self.storage_server.get(fid)

        if fkeys == None:
            return self.make_file_keys(fid)
        else:
            owner, encrypted_original_filename = self.get_owner_and_encrypted_original_filename(
                name)

            if self.username != owner:
                kid = path_join(self.username, encrypted_original_filename,
                                "keys")
                keys_string = self.storage_server.get(kid)
                if not keys_string:
                    return None
                else:
                    try:
                        encrypted_keys_string, signed_encrypted_keys_string = util.from_json_string(
                            keys_string[7:])
                    except:
                        raise IntegrityError()

                if self.crypto.asymmetric_verify(
                        encrypted_keys_string, signed_encrypted_keys_string,
                        self.pks.get_public_key(owner)):
                    keys_string = self.crypto.asymmetric_decrypt(
                        encrypted_keys_string, self.private_key)
                    self.sign_and_store(keys_string, self.username, kid)
                elif self.crypto.asymmetric_verify(
                        encrypted_keys_string, signed_encrypted_keys_string,
                        self.pks.get_public_key(self.username)):
                    pass
                else:
                    raise IntegrityError()

            keys_string = self.verify_signature_and_get_value(
                self.username, fid)
            keys = util.from_json_string(keys_string)
            return keys
示例#20
0
    def safe_decrypt(self, resp):
        pub_key = self.private_key.publickey()

        try:
            key_info = util.from_json_string(resp)
            encrypted_keys = key_info["encrypted_keys"]
            signed_keys = key_info["signed_keys"]
        except:
            raise IntegrityError()

        if not self.crypto.asymmetric_verify(encrypted_keys, signed_keys,
                                             pub_key):
            raise IntegrityError()

        decrypted_keys = self.crypto.asymmetric_decrypt(
            encrypted_keys, self.private_key)
        return util.from_json_string(decrypted_keys)
示例#21
0
    def upload(self, name, value):
        # Get symmetric keys
        ke, km, kn = self.get_symmetric_keys()
        # Get ID for the key node of file NAME
        uid = self.get_kid(name, kn)
        # Get Ke, Km, and did for data node
        res = self.resolve(uid, ke, km)
        if res is None:
            # Create new data node
            ke2, km2, _ = self.new_symmetric_keys()
            did = self.new_did()
            key_node_v = "[POINTER]{0}||{1}||{2}".format(ke2, km2, did)
            key_node_v_enc = self.encrypt_value_for_storage(
                uid, key_node_v, ke, km)
            self.storage_server.put(uid, key_node_v_enc)
            uid = did
            ke, km = ke2, km2
            isNew = True
        else:
            ke, km, uid, _ = res
            isNew = False

        tree = LocalMerkleTree(self.hash, uid=uid)
        tree.initialize(value, blocksize=1024, uid_gen=self.new_did)

        if name not in self.trees:
            if isNew:
                self.upload_updates(tree.all_nodes(), ke, km)
            else:
                server_root = self.get_server_node(uid, ke, km)
                if tree.length <= server_root["n"]:
                    self.efficient_update(tree, ke, km)
                else:
                    self.delete_server_tree(uid, ke, km)
                    self.upload_updates(tree.all_nodes(), ke, km)
            self.trees[name] = tree
        else:
            if isNew: raise IntegrityError()
            local_tree = self.trees[name]
            server_root = self.get_server_node(uid, ke, km)
            tree.update_uids(local_tree.all_uids())

            if local_tree.hash == server_root["h"]:
                if local_tree.length >= tree.length:
                    self.upload_updates(local_tree.compare_and_update(tree),
                                        ke, km)
                    self.trees[name] = local_tree
                else:
                    self.delete_server_tree(uid, ke, km)
                    self.upload_updates(tree.all_nodes(), ke, km)
                    self.trees[name] = tree
            else:
                if local_tree.length >= tree.length:
                    self.efficient_update(tree, ke, km)
                else:
                    self.delete_server_tree(uid, ke, km)
                    self.upload_updates(tree.all_nodes(), ke, km)
                self.trees[name] = tree
示例#22
0
 def resolve(self, uid):
     while True:
         res = self.storage_server.get(uid)
         if res is None or res.startswith("[DATA]"):
             return uid
         elif res.startswith("[POINTER]"):
             uid = res[10:]
         else:
             raise IntegrityError()
示例#23
0
 def resolve(self, uid):
     """Follows [P]'s until we reach the a None or [D]"""
     while True:
         res = self.storage_server.get(uid)
         if res is None or res.startswith("[D]"):
             return uid
         elif res.startswith("[P]"):
             uid = res[4:]
         else:
             raise IntegrityError()
示例#24
0
    def verify_signature_and_get_value(self, signer, data_id):
        value_string = self.storage_server.get(data_id)
        if not value_string:
            return None
        else:
            try:
                encrypted_content, signed_encrypted_content = util.from_json_string(
                    value_string[7:])
            except:
                raise IntegrityError()

            if self.crypto.asymmetric_verify(encrypted_content,
                                             signed_encrypted_content,
                                             self.pks.get_public_key(signer)):
                decrypted_content = self.crypto.asymmetric_decrypt(
                    encrypted_content, self.private_key)
                return decrypted_content
            else:
                raise IntegrityError()
示例#25
0
    def decrypt_directory(self, resp, sym_ke, sym_ka):
        try:
            directory_info = util.from_json_string(resp)
            IV = directory_info['IV']
            encrypted_keys = directory_info["encrypted_keys"]
            signed_keys = directory_info["signed_keys"]
        except:
            raise IntegrityError()

        signed_dir = self.crypto.message_authentication_code(
            encrypted_keys, sym_ka, 'SHA256')
        if signed_dir != signed_keys:
            raise IntegrityError()

        directory = self.crypto.symmetric_decrypt(encrypted_keys, sym_ke,
                                                  'AES', 'CBC', IV)
        directory = util.from_json_string(directory)

        return directory
示例#26
0
    def getRoot(self, ID, sym_ka):
        meta = self.storage_server.get(path_join(ID, str(0)))

        if meta is None:
            return None
        try:
            meta = util.from_json_string(meta)
            numblocks = meta['numblocks']
            mac = meta['mac']

            meta_mac = self.crypto.message_authentication_code(
                str(numblocks), sym_ka, 'SHA')  #SHA

            if meta_mac != mac:
                raise IntegrityError()
        except:
            raise IntegrityError()

        return numblocks
示例#27
0
    def get_shared_info(
        self, uid, data_key, data_mac_key
    ):  #add stuff to decrypt the [DATA] [random_id, random_key] #get decrypted value of random_id
        try:
            list_of_data_items_as_string = self.storage_server.get(uid)[7:]
            list_of_data_items = util.from_json_string(
                list_of_data_items_as_string)

            data_iv = list_of_data_items[0]

            encrypted_data_as_string = list_of_data_items[1]

            data_mac = list_of_data_items[2]
            calculated_data_mac = self.crypto.message_authentication_code(
                encrypted_data_as_string, data_mac_key, 'SHA256')
            if calculated_data_mac != data_mac:
                raise IntegrityError()
            shared_info = self.crypto.symmetric_decrypt(
                encrypted_data_as_string, data_key, 'AES', 'CBC', data_iv)
            info_as_list = util.from_json_string(shared_info)
            random_id = info_as_list[0]
            random_key_for_value = info_as_list[1]
            random_key_for_value_mac = info_as_list[2]
            resp = self.storage_server.get(random_id)
            if resp is None:
                return None
            list_of_value_items_as_string = resp[7:]
            list_of_value_items = util.from_json_string(
                list_of_value_items_as_string)
            value_iv = list_of_value_items[0]
            encrypted_value = list_of_value_items[1]
            name_and_value_encrypt_mac = list_of_value_items[2]
            calculated_mac = self.crypto.message_authentication_code(
                random_id + encrypted_value, random_key_for_value_mac,
                'SHA256')
            if calculated_mac != name_and_value_encrypt_mac:
                raise IntegrityError()
            decrypted_value = self.crypto.symmetric_decrypt(
                encrypted_value, random_key_for_value, 'AES', 'CBC', value_iv)
            return decrypted_value
        except:
            raise IntegrityError()
示例#28
0
    def checkTreeNode(self, path, sym_Ka):
        resp = self.storage_server.get(path)

        if resp is None:
            return None
        try:
            resp = util.from_json_string(resp)
        except:
            raise IntegrityError()

        stored_hash = resp['hash']
        mac = resp['mac']

        newmac = self.crypto.message_authentication_code(
            stored_hash, sym_Ka, 'SHA')  #SHA

        if mac != newmac:
            raise IntegrityError()

        return stored_hash
示例#29
0
 def resolve(self, uid, ke, km):
     node = self.decrypt_values_at_id(uid, ke, km)
     # resolve pointers until we reach a data node
     while True:
         if node is None:
             return None
         elif self.is_data_node(node):
             return ke, km, uid, node
         elif self.is_pointer_node(node):
             ke, km, uid = self.parse_pointer_node(node)
         else:
             raise IntegrityError()
         node = self.decrypt_values_at_id(uid, ke, km)
示例#30
0
    def share(self, user, name):
        # Replace with your implementation (not needed for Part 1)
        uid = path_join(self.username, name)
        username_keys = path_join(self.username, "dict_keys")
        username_dictionary = path_join(self.username, "dictionary")
        random_key_for_dictionary = self.storage_server.get(username_keys)
        #print(random_key_for_dictionary)
        random_key_for_dictionary = self.crypto.asymmetric_decrypt(random_key_for_dictionary, self.private_key)
        dictionary_items_as_string = self.storage_server.get(username_dictionary)

        #print(dictionary_items_as_string)
        if dictionary_items_as_string is None:
                return None
        dictionary_items_as_list = util.from_json_string(dictionary_items_as_string)
        dictionary_iv = dictionary_items_as_list[0]
        encrypted_dictionary = dictionary_items_as_list[1]
        decrypted_dictionary = self.crypto.symmetric_decrypt(encrypted_dictionary, random_key_for_dictionary, 'AES', 'CBC', dictionary_iv)
        actual_dictionary = util.from_json_string(decrypted_dictionary)

        random_keys = actual_dictionary.get(uid)
        #print(random_keys)
        if random_keys is None:
            return None
        random_id = random_keys[0]
        random_id_key = random_keys[1]
        random_id_mac = random_keys[2]


        e_key = self.crypto.asymmetric_encrypt(random_id_key, self.public_key_server.get_public_key(user))

        if self.storage_server.get(random_id+"shared_file") == None:
            shared_dict_as_string = util.to_json_string({self.username: None}) #SHADYYYYYYYYYYY; how do you initialize shizzzzzzzz
            #don't need to encrypt shared_dict since it's public info
            shared_dict_mac = self.crypto.message_authentication_code(shared_dict_as_string, random_id_key, 'SHA256')
            shared_dict_values = [shared_dict_as_string, shared_dict_mac]
            shared_dict_values_as_string = util.to_json_string(shared_dict_values)
            self.storage_server.put(random_id+"shared_file", shared_dict_values_as_string)

        shared_dict = self.storage_server.get(random_id+"shared_file")
        calculated_mac = self.crypto.message_authentication_code(shared_dict, random_id_key, 'SHA256')
        if calculated_mac != shared_dict[1]:
            raise IntegrityError() #is this the right error
        shared_dict = util.from_json_string(shared_dict)
        shared_dict[self.username] = shared_dict[self.username].append({user: None})

        msg_as_list = [random_id, e_key, random_id+"shared_file"]
        msg_as_string = util.to_json_string(msg_as_list)

        #they're not gonna test if you call share on something you don't own
        #return None if a user tries to download a file that they don't have access to, not IntegrityError()
        return msg_as_string