def find(self, keyword): """ 执行搜索操作 :param keyword: 待搜索的关键词 :return: """ def save_result(): try: if not os.path.isdir(self.proj_dir_path + 'search_results'): os.mkdir(self.proj_dir_path + 'search_results') DIR = self.proj_dir_path + 'search_results/' + keyword if not os.path.isdir(DIR): os.mkdir(DIR) DIR += '/' for index in res: tmp = download_manager.download_from_server_given_client_and_decrypt(self, index) printer.print_info(tmp[0]) # 打印出相应的标题 with open(DIR + tmp[0], 'w', encoding='UTF-8') as f: f.write(tmp[1]) printer.print_info('搜索结果已经保存在目录 ' + DIR + ' 中。') except OSError: printer.print_error('由于系统限制,指定的关键词无法搜索!') def search_action(): return search_manager.search_once_from_server(self, keyword) if get_status_by_bits(self.status_bits) != 1: printer.print_error('操作失败,理由: ') self.status() return res = search_action() printer.print_info('搜索结果如下:') save_result()
def generate_keys(self): """ 生成密钥(k1,k2,k3,k4) :return: """ def generate_keys_action(): k1, k2, k3, k4 = self.gen() print('========THE KEY========') print('{}\n{}\n{}\n{}'.format(base64.b64encode(k1).decode(encoding='UTF-8'), base64.b64encode(k2).decode(encoding='UTF-8'), base64.b64encode(k3).decode(encoding='UTF-8'), base64.b64encode(k4).decode(encoding='UTF-8'))) print('========THE KEY========') # 保存密钥 self.save_keys() printer.print_success('密钥文件已保存至本地.') if 2 <= get_status_by_bits(self.status_bits) < 4 or get_status_by_bits(self.status_bits) == 7: # 前面的步骤没有完成时 printer.print_error('操作失败,理由: ') self.status() return if get_status_by_bits(self.status_bits) == 6 or get_status_by_bits(self.status_bits) == 1: # 如果之前已经有了密文集或者已经上传到了服务器 # 需要告知用户谨慎生成密钥文件 printer.print_warning('已发现使用旧密钥加密后的密文集和索引,重新生成密钥需要重新自行执行enc和upload方法进行同步更新.\n' '是否需要继续? (Y/N)') ok = input() if ok == 'Y' or ok == 'y': generate_keys_action() else: printer.print_info('程序没有进行任何操作,退出...') generate_keys_action()
def save_result(): try: if not os.path.isdir(self.proj_dir_path + 'search_results'): os.mkdir(self.proj_dir_path + 'search_results') DIR = self.proj_dir_path + 'search_results/' + keyword if not os.path.isdir(DIR): os.mkdir(DIR) DIR += '/' for index in res: tmp = download_manager.download_from_server_given_client_and_decrypt(self, index) printer.print_info(tmp[0]) # 打印出相应的标题 with open(DIR + tmp[0], 'w', encoding='UTF-8') as f: f.write(tmp[1]) printer.print_info('搜索结果已经保存在目录 ' + DIR + ' 中。') except OSError: printer.print_error('由于系统限制,指定的关键词无法搜索!')
def init(self): """ 初始化proj,即新建目录,并在该目录下新建明文和密文目录 :return: None """ def init_action(): if os.path.isdir(self.proj_name): # 如果已经存在项目目录,就需要递归删除该目录 # os.removedirs(self.proj_name) shutil.rmtree(self.proj_name) os.mkdir(self.proj_name) os.mkdir(self.proj_dir_path + 'plain_text') os.mkdir(self.proj_dir_path + 'cipher_text') # 接下来,还要保存配置文件 with open(self.proj_dir_path + 'config', 'wb') as f: pickle.dump([self.k, self.l, self.s, self.file_cnt], f) if os.path.isdir(self.proj_name): printer.print_warning("发现已经存在同名目录,是否需要清除该目录下所有内容? (Y/N)") ok = input() if ok == 'Y' or ok == 'y': printer.print_info("正在清空并初始化中...") init_action() printer.print_success("清空完成!") else: printer.print_info("用户已拒绝操作,程序退出...") return else: printer.print_info("正在初始化项目中...") init_action() printer.print_success("初始化项目完成!")
def status(self): """ 获取当前项目的状态 2: 项目不存在 --> 目录不存在 3: 明文集不存在 --> 如果项目目录和子目录plain_text都为空 --> 既没有明文,又没有密钥文件 --> & 01010 == 0 4: 未执行gen()方法 --> 不存在密钥文件 --> & 00010 == 0 5: 未执行enc()方法 --> 存在明文集和密钥文件,但不存在密文集和加密后的索引文件 --> & 01110 == 01010 -> 10 6: 未执行上传操作 --> 如果存在密文集 --> & 00100 == 0 7: 哈希不一致 1: 成功 :return: None """ status_details_dict = { 1: "当前项目已经可以进行加密搜索。", 2: "项目不存在。", 3: "明文集不存在。", 4: "该项目未执行gen方法生成密钥。", 5: "该项目未执行enc方法进行加密操作。", 6: "该项目已经在本地部署完毕,但仍未上传到服务器。", 7: "该项目似乎在服务器遭到破坏,请重新生成" } status_id = get_status_by_bits(self.status_bits) printer.print_info(status_details_dict[status_id])
def encrypt_action(): printer.print_info('检查明文目录下文件名格式是否符合要求...') if not scanner.check_filename_format(self.proj_dir_path): printer.print_info('不符合文件命名格式,请问是否需要执行自动格式化文件名操作? (Y/N)') ok = input() if ok == 'y' or ok == 'Y': scanner.reformat_filename(self.proj_dir_path) printer.print_success('格式化文件名成功!') else: printer.print_error('软件终止...请自行更改文件名以满足要求!') else: printer.print_success('检查完毕,文件名符合要求!') printer.print_info('开始加密索引和文档...') self.enc() self.save_encrypted_index() # 记得保存索引 printer.print_success('加密索引和文档成功')
def get_file(printer, adb, su, source, destination): tmp_dir = check_tmp(printer, adb, su) file_name = os.path.basename(source) tmp_dest = "%s/%s" % (tmp_dir, file_name) ''' Copy the file to the TEMP folder ''' out = adb.shell_command(su + "'cat %s >%s'" % (source, tmp_dest)) if ((out != None) and (out.find("Read-only") != -1)): printer.print_err( "The /tmp directory is readonly! Let's use /data/local/tmp") tmp_dir = "/data/local/tmp" out = adb.shell_command(su + "'cat %s >%s'" % (source, tmp_dest)) if (out != None): printer.print_err("Unknown error: %s!" % (out)) return -1 ''' Change the permissions to be able to read the file''' out = adb.shell_command(su + "chmod 666 %s" % (tmp_dest)) if (out != None): printer.print_err("Unknown error: %s!" % (out)) printer.print_info( "Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!" % tmp_dir) out = adb.shell_command(su + "rm %s" % tmp_dest) if (out == None): printer.print_ok("Clean up - Done") return -1 ''' Download the file from the TEMP folder''' pull = adb.get_remote_file("%s" % tmp_dest, "%s" % destination) if (pull.find("bytes") == -1): printer.print_err("Could not download the file: %s" % pull) printer.print_info( "Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!" % tmp_dir) out = adb.shell_command(su + "rm %s" % tmp_dest) if (out == None): printer.print_ok("Clean up - Done") return -1 '''self.printer.print_info(pull.rstrip("\n"))''' ''' cleanup''' printer.print_info( "Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!" % tmp_dir) out = adb.shell_command(su + "rm %s" % tmp_dest) if (out == None): printer.print_ok("Clean up - Done") return pull
def get_file(printer, adb, su, source, destination): tmp_dir = check_tmp(printer,adb,su) file_name = os.path.basename(source) tmp_dest = "%s/%s" % (tmp_dir,file_name) ''' Copy the file to the TEMP folder ''' out=adb.shell_command(su+"'cat %s >%s'" % (source,tmp_dest)) if( (out!=None) and (out.find("Read-only")!=-1) ): printer.print_err("The /tmp directory is readonly! Let's use /data/local/tmp") tmp_dir="/data/local/tmp" out=adb.shell_command(su+"'cat %s >%s'" % (source,tmp_dest)) if(out!=None): printer.print_err("Unknown error: %s!" % (out)) return -1 ''' Change the permissions to be able to read the file''' out=adb.shell_command(su+"chmod 666 %s" % (tmp_dest)) if(out!=None): printer.print_err("Unknown error: %s!" % (out)) printer.print_info("Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!" % tmp_dir) out=adb.shell_command(su+"rm %s" % tmp_dest) if (out==None): printer.print_ok("Clean up - Done") return -1 ''' Download the file from the TEMP folder''' pull=adb.get_remote_file("%s" % tmp_dest,"%s" % destination) if(pull.find("bytes")==-1): printer.print_err("Could not download the file: %s" % pull) printer.print_info("Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!" % tmp_dir) out=adb.shell_command(su+"rm %s" % tmp_dest) if (out==None): printer.print_ok("Clean up - Done") return -1 '''self.printer.print_info(pull.rstrip("\n"))''' ''' cleanup''' printer.print_info("Cleaning up! Please check the %s folder. Unsuccessull cleanup weakens the security of the phone!!!!" % tmp_dir) out=adb.shell_command(su+"rm %s" % tmp_dest) if (out==None): printer.print_ok("Clean up - Done") return pull
def enc(self): def initialization(): # step1. scan D and generate the set of distinct keywords δ(D) self.distinct_word_set = scanner.generate_the_set_of_distinct_keywords_for_docs(self.proj_dir_path)[1] # step2. for all w ∈ δ(D), generate D(w) self.D_ = scanner.generate_Dw_for_each_keyword(self.proj_dir_path) # step3. initialize a global counter ctr = 1 ---> see __init__() def building_the_array_A(): # step4. for 1<=i<=|δ(D)|, build a list Li with nodes Ni,j and store it in array A as follows: for i in range(1, len(self.distinct_word_set) + 1): keyword = self.distinct_word_set[i - 1] # 在这里注意论文中的i和程序中的i不同,应当减一 Ki = [None] * (len(self.D_[keyword]) + 1) Ni = [None] * (len(self.D_[keyword]) + 1) # sample a key Ki,0 <-$- {0, 1}^k Ki[0] = Random.new().read(int(self.k / 8)) self.k0_for_each_keyword[keyword] = Ki[0] # for 1<=j<=|D(wi)|-1 j = 0 for j in range(1, len(self.D_[keyword])): # let id(Di,j) be the jth identifier in D(wi) id_Dij = self.D_[keyword][j - 1] # todo # generate a key Ki,j <- SKE1.Gen(1^k) Ki[j] = Random.new().read(int(self.k / 8)) # if j == 1: # self.k0_for_each_keyword[keyword] = Ki[j] # Ni[j] = str(id_Dij) + "|||" + str(Ki[j]) + "|||" + self.mu(Ki[j - 1], Ni[j]) Ni[j] = id_Dij.to_bytes(self.file_cnt_byte, byteorder="big") + Ki[j] + self.mu(self.k1, num2byte( self.ctr + 1, int(self.s / 8))) index = self.mu(self.k1, num2byte(self.ctr, int(self.s / 8))) if j == 1: self.addrA[keyword] = index # 保存头节点的地址到dict里面去 index = int.from_bytes(index, byteorder="big") self.A[index] = self.SKEEnc(Ki[j - 1], Ni[j]) if self.entry_size_of_A == -1: self.entry_size_of_A = len(self.A[index]) self.ctr += 1 # for the last node of Li # set the address of the next node to NULL: Ni,|D(wi)| = <id(Di,|D(wi)|) || 0^k || NULL> j += 1 # ... id_Dij = self.D_[keyword][len(self.D_[keyword]) - 1] Ni[len(self.D_[keyword])] = id_Dij.to_bytes(self.file_cnt_byte, byteorder="big") + b"\x00" * int( self.k / 8) + b"\x00" * int(math.ceil(self.s / 8)) # todo index = self.mu(self.k1, num2byte(self.ctr, int(self.s / 8))) if j == 1: self.addrA[keyword] = index # 保存头节点的地址到dict里面去 # self.k0_for_each_keyword[keyword] = Ki[j] index = int.from_bytes(index, byteorder="big") self.A[index] = self.SKEEnc(Ki[j - 1], Ni[len(self.D_[keyword])]) # encrypt the node Ni,|D(wi)| under the key Ki,|D(wi)-1| and store it in A self.ctr += 1 # step5. set the remaining s - s' entries of A to random values of the same size # as the existing s' entries of A for i in range(len(self.A)): if self.A[i] is None: self.A[i] = Random.new().read(self.entry_size_of_A) def building_the_look_up_table_T(): size = -1 # size为look-up table 中元素的长度,用于第7个步骤 # step6. for all wi ∈ δ(D), set T[π_K3(wi)] = <addr_A(N_i,1 || K_i,0)> ⊕ f_K2(wi) for w in self.distinct_word_set: index = self.pi(self.k3, str2byte(w)) index = int.from_bytes(index, byteorder="big") self.T[index] = self.xor(self.addrA[w] + self.k0_for_each_keyword[w], self.f(self.k2, str2byte(w))) if size == -1: size = len(self.T[index]) # step7. if |δ(D)| < |△|, then set the remaining |△| - |δ(D)| entries of T to random values of the # same size as the existing |δ(D)| entries of T for i in range(2 ** self.l): if self.T[i] is None: self.T[i] = Random.new().read(size) def enc_docs(): # step8. for 1 <= i <= n, let ci <- SKE2.Enc_K4(Di) DIR = 'plain_text' file_count = len([name for name in os.listdir(DIR) if os.path.isfile(os.path.join(DIR, name))]) for i in range(file_count): self.enc_doc(i, self.k4) printer.print_info('创建索引中...') initialization() printer.print_info('加密索引中...') building_the_array_A() building_the_look_up_table_T() printer.print_info('加密文档中...') enc_docs() printer.print_success('已就绪.') # step9. output return self.A, self.T