栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python 文件加密存储到mongodb tkinter AES

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python 文件加密存储到mongodb tkinter AES

Select your file and store it encrypted in mongodb

文件加密存储到mongodb 密码随文件一同存储到头尾部,正式环境请妥善保管密码!

应用的模块有 tkinter(Button Treeview Text Entry) pymongo(文件操作 增 删 查询) Cryptodome的AES加密

最大上传测试文件 13,003,362 字节 13M

一、选择文件  点上传进行存储(加密过程序中随机生成key iv)

二、搜索, 列表前10条已上传文件(可模糊查询,过滤类型,目前只写了rar类型)

三、点列表中搜索结果,可进行单条下载(下到程序同目录),或者单条删除

四、Talk is cheap.Show me your code

# -*- coding:utf-8 -*-
# @FileName  :ide1.py
# @Time      :2022/5/12 19:33
import os
import tkinter.messagebox as msgbox
from tkinter import *
import tkinter as tk
import tkinter.font as tkFont
from tkinter import filedialog, ttk

import pymongo
import gridfs

from bson import ObjectId
from Cryptodome.Cipher import AES
from Cryptodome import Random
from pymongo.server_api import ServerApi
import pandas as pd

class App:
    def __init__(self, root):
        uri = "mongodb+srv://user:password@cloud.youdomain.com/myFirstDatabase?retryWrites=true&w=majority"
        self.client = pymongo.MongoClient(uri, server_api=ServerApi('1'))
        self.db = self.client['files']
        self.fs_rar = gridfs.GridFS(self.db, 'rar')
        self.coll = self.db["rar.files"]

        pd.set_option('display.max_rows', 500)
        pd.set_option('display.max_columns', 200)  # pd.set_option('display.max_columns', None)
        pd.set_option('display.width', 1000)

        self.iv = Random.new().read(AES.block_size)
        self.key = Random.new().read(AES.block_size)
        title=''

        try:
            dblist = self.client.list_database_names()
            if dblist:
                # root.write_log_to_Text('数据库连接成功')
                title='数据库连接成功'
                # print(dblist)
        except:
            # root.write_log_to_Text('数据库连接失败')
            title = '数据库连接失败'





        #setting title
        # root.title("file2mongodb")
        root.title(title)
        #setting window size
        width=399
        height=329
        screenwidth = root.winfo_screenwidth()
        screenheight = root.winfo_screenheight()
        alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        root.geometry(alignstr)
        root.resizable(width=False, height=False)

        # 初始化Entry控件的textvariable属性值.
        self.select_path = tk.StringVar()
        GLineEdit_path=tk.Entry(root, textvariable = self.select_path)
        GLineEdit_path["borderwidth"] = "1px"
        ft = tkFont.Font(family='Times',size=10)
        GLineEdit_path["font"] = ft
        GLineEdit_path["fg"] = "#333333"
        GLineEdit_path["justify"] = "left"
        GLineEdit_path["relief"] = "flat"
        GLineEdit_path.place(x=70,y=10,width=221,height=30)

        GButton_upload=tk.Button(root)
        GButton_upload["bg"] = "#efefef"
        ft = tkFont.Font(family='Times',size=10)
        GButton_upload["font"] = ft
        GButton_upload["fg"] = "#000000"
        GButton_upload["justify"] = "center"
        GButton_upload["text"] = "上 传"
        GButton_upload["relief"] = "groove"
        GButton_upload.place(x=300,y=10,width=93,height=30)
        GButton_upload["command"] = self.GButton_upload_command

        #
        # GLineEdit_916=tk.Text(root) #主显示
        # GLineEdit_916["borderwidth"] = "1px"
        # ft = tkFont.Font(family='Times',size=10)
        # GLineEdit_916["font"] = ft
        # GLineEdit_916["fg"] = "#333333"
        # GLineEdit_916["relief"] = "flat"
        # GLineEdit_916.place(x=10,y=130,width=383,height=152)

        title = ('id', 'name',   'length')
        self.tv = ttk.Treeview(root, columns=title, show='headings', height=8)
        # self.tv.pack()
        for i in range(len(title)):
            self.tv.column(title[i], width=10, anchor='e')
            self.tv.heading(title[i], text=title[i])
        self.tv.column(0, width=100)
        self.tv.place(x=10, y=130, width=383, height=152)
        self.tv.bind("", self.selectItem)

        # def popup(event):
        #     "鼠标事件"
        #     item = self.tv.selection()[0]
        #     print( ", it's values = ", self.tv.item(item, "values"))
        #     print('___________________')
        #
        # # self.tv.bind("", popup)
        # self.tv.bind("", popup)

        GButton_download=tk.Button(root)
        GButton_download["bg"] = "#efefef"
        ft = tkFont.Font(family='Times',size=10)
        GButton_download["font"] = ft
        GButton_download["fg"] = "#000000"
        GButton_download["justify"] = "center"
        GButton_download["text"] = "下 载"
        GButton_download["relief"] = "groove"
        GButton_download.place(x=300,y=50,width=94,height=30)
        GButton_download["command"] = self.GButton_download_command

        # 初始化Entry控件的textvariable属性值
        self.text_status = tk.StringVar()
        self.GLineEdit_778=tk.Entry(root, textvariable=self.text_status)  #状态
        self.GLineEdit_778["borderwidth"] = "1px"
        ft = tkFont.Font(family='Times',size=10)
        self.GLineEdit_778["font"] = ft
        self.GLineEdit_778["fg"] = "#333333"
        self.GLineEdit_778["justify"] = "center"
        self.GLineEdit_778["relief"] = "groove"
        self.GLineEdit_778.place(x=10,y=290,width=379,height=30)

        self.text_search = tk.StringVar()
        self.GLineEdit_search=tk.Entry(root, textvariable=self.text_search)  #搜索
        self.GLineEdit_search["borderwidth"] = "1px"
        ft = tkFont.Font(family='Times',size=10)
        self.GLineEdit_search["font"] = ft
        self.GLineEdit_search["fg"] = "#333333"
        self.GLineEdit_search["justify"] = "left"

        self. GLineEdit_search["relief"] = "flat"
        self.GLineEdit_search.place(x=70,y=50,width=221,height=30)

        self.valrar = IntVar()
        GCheckBox_rar=tk.Checkbutton(root, variable=self.valrar)
        ft = tkFont.Font(family='Times',size=10)
        GCheckBox_rar["font"] = ft
        GCheckBox_rar["fg"] = "#333333"
        GCheckBox_rar["justify"] = "center"
        GCheckBox_rar["text"] = "RAR"
        GCheckBox_rar["relief"] = "flat"
        GCheckBox_rar.place(x=20,y=90,width=53,height=30)
        GCheckBox_rar["offvalue"] = "0"
        GCheckBox_rar["onvalue"] = "1"
        GCheckBox_rar["command"] = self.GCheckBox_rar_command

        GCheckBox_125=tk.Checkbutton(root)
        ft = tkFont.Font(family='Times',size=10)
        GCheckBox_125["font"] = ft
        GCheckBox_125["fg"] = "#333333"
        GCheckBox_125["justify"] = "center"
        GCheckBox_125["text"] = "TXT"
        GCheckBox_125["relief"] = "flat"
        GCheckBox_125.place(x=100,y=90,width=51,height=30)
        GCheckBox_125["offvalue"] = "0"
        GCheckBox_125["onvalue"] = "1"
        GCheckBox_125["command"] = self.GCheckBox_125_command

        GCheckBox_45=tk.Checkbutton(root)
        ft = tkFont.Font(family='Times',size=10)
        GCheckBox_45["font"] = ft
        GCheckBox_45["fg"] = "#333333"
        GCheckBox_45["justify"] = "center"
        GCheckBox_45["text"] = "Excel"
        GCheckBox_45["relief"] = "flat"
        GCheckBox_45.place(x=170,y=90,width=64,height=30)
        GCheckBox_45["offvalue"] = "0"
        GCheckBox_45["onvalue"] = "1"
        GCheckBox_45["command"] = self.GCheckBox_45_command

        self.valother = IntVar()
        GCheckBox_other=tk.Checkbutton(root, variable=self.valother)
        ft = tkFont.Font(family='Times',size=10)
        GCheckBox_other["font"] = ft
        GCheckBox_other["fg"] = "#333333"
        GCheckBox_other["justify"] = "center"
        GCheckBox_other["text"] = "Other"
        GCheckBox_other["relief"] = "flat"
        GCheckBox_other.place(x=240,y=90,width=56,height=30)
        GCheckBox_other["offvalue"] = "0"
        GCheckBox_other["onvalue"] = "1"
        GCheckBox_other["command"] = self.GCheckBox_other_command

        GButton_delete=tk.Button(root)
        GButton_delete["bg"] = "#efefef"
        ft = tkFont.Font(family='Times',size=10)
        GButton_delete["font"] = ft
        GButton_delete["fg"] = "#000000"
        GButton_delete["justify"] = "center"
        GButton_delete["text"] = "删 除"
        GButton_delete["relief"] = "groove"
        GButton_delete.place(x=300,y=90,width=91,height=30)
        GButton_delete["command"] = self.GButton_delete_command

        GButton_90=tk.Button(root)
        GButton_90["bg"] = "#efefef"
        ft = tkFont.Font(family='Times',size=10)
        GButton_90["font"] = ft
        GButton_90["fg"] = "#000000"
        GButton_90["justify"] = "center"
        GButton_90["text"] = "选择文件"
        GButton_90["relief"] = "flat"
        GButton_90.place(x=0,y=10,width=66,height=30)
        GButton_90["command"] = self.GButton_90_command

        GButton_search=tk.Button(root)
        GButton_search["bg"] = "#efefef"
        ft = tkFont.Font(family='Times',size=10)
        GButton_search["font"] = ft
        GButton_search["fg"] = "#000000"
        GButton_search["justify"] = "center"
        GButton_search["text"] = "搜索文件"
        GButton_search["relief"] = "flat"
        GButton_search.place(x=0,y=50,width=66,height=30)
        GButton_search["command"] = self.GButton_search_command



    def GButton_upload_command(self):
        self.text_status.set('上传')
        # self.select_path.set('D:/workspace/pythonProject/zszm/mongo/2.rar')
        if self.select_path.get():
            path = self.select_path.get()
            fileName = os.path.split(path)[1]
            print(fileName)
            self.text_status.set(fileName)
            id = self.findFileByName(fileName)
            rewrite = 1
            if id and rewrite == 0:
                self.text_status.set('%s文件存在,停止上传:%s' % (fileName,id))
                self.text_search.set(fileName)
            else:
                id = self.save_file_to_mongo(path, '', rewrite)
                if id:
                    self.text_search.set(fileName)
                    self.text_status.set('%s文件上传成功:%s' % (fileName,id))
                    self.GButton_search_command()

        else:
            self.text_status.set('未选择上传文件')



    def GButton_download_command(self):
        # print("command247")
        # self.text_status.set('文件保存成功:627d28720dc2723480ee1e7a')
        print(os.getcwd())
        downloadID  = self.text_status.get()
        # print(downloadID)
        if downloadID and len(downloadID.split(':'))>1:
            id = downloadID.split(':')[1]
            print(len(id))
            if len(id) == 24:
                fileName = self.findFileByID(id)
            # print(fileName)
                if fileName:
                    sp = fileName.split('.')
                    fileName = sp[0] + '_db.' + sp[1]
                    # print(fileName)
                    self.write_to_disk(fileName, self.get_file_from_mongo(id))

                    self.text_status.set('%s写入硬盘%s\' % (fileName,os.getcwd()))
                else:
                    self.text_status.set('未发现id为%s的文件'%id )
            else:
                self.text_status.set('_id输入不正确')
        else:
            self.text_status.set('_id为空')

        # 文件保存成功:627d227c499b77d0150a0c15



    def GCheckBox_rar_command(self):
        print("command304")
        self.text_status.set('command304')


    def GCheckBox_125_command(self):
        print("command125")
        self.text_status.set('command125')


    def GCheckBox_45_command(self):
        print("command45")
        self.text_status.set('command45')


    def GCheckBox_other_command(self):
        print("command214")
        print(self.valother.get())
        self.text_status.set('command214')


    def GButton_delete_command(self):
        print("command730")
        # self.text_status.set('command730')
        id = self.text_status.get()
        if id and len(id.split(':'))>1:
            id = id.split(':')[1]
        if id and len(id) == 24:
            b=msgbox.askokcancel('确认操作', '真的要删除编号为%s的文件么?'%id)  # 返回值true/false
            # print(b)
            if b:
                # id = self.text_status.get()
                print(id)
                re = self.fs_rar.delete(ObjectId(id))
                print(re)


    def GButton_90_command(self):
        print("command90")
        # 单个文件选择
        selected_file_path = filedialog.askopenfilename()  # 使用askopenfilename函数选择单个文件
        self.select_path.set(selected_file_path)



    def GButton_search_command(self): #搜索
        print('command209')
        fileName =self.text_search.get()
        args = {}
        if fileName:
            args['filename'] = {'$regex':fileName}
        if self.valrar.get()==1:
            args['type'] = 'rar'
        print(args)
        result = self.coll.find(args).limit(10)
        print(result)
        # df = pd.DataFrame(list(result))
        # print(df)
        for row in  self.tv.get_children():
            self.tv.delete(row)
        for row in result:
            self.tv.insert('', 'end', values=(row['_id'],row['filename'],row['length']))

    def selectItem(self,event):
        curItem = self.tv.focus()
        # print (self.tv.item(curItem))
        list1 = self.tv.item(curItem)['values']
        # print(list1)
        if list1 and len(list1)>2:
            self.text_status.set('%s大小%s ID为:%s'%(list1[1],list1[2],list1[0]))

    def findFileByName(self,fileName):
        back =self.coll.find_one({"filename": fileName})
        if back:
            return back['_id']
        else:
            return back
        # 存储文件到mongo
    def findFileByID(self,id):
        back =self.coll.find_one({"_id": ObjectId(id)})
        # print(back)
        if back:
            return back['filename']
        else:
            return back
    def save_file_to_mongo(self, path, keyword, rewrite=0):

        fileName = os.path.split(path)[1]
        id = self.findFileByName(fileName)
        if id and rewrite == 0:
            print('文件存在,直接返回id')
            return id
        else:
            args = {}
            args['keyword'] = keyword
            args['type'] = fileName.split('.')[1]
            # args['key'] = self.key
            with open(path, 'rb') as f:
                data = f.read()
            data = self.encrypt(data)
            return self.fs_rar.put(data, filename=fileName, **args)

    def encrypt(self, data):
        cipher = AES.new(self.key, AES.MODE_CFB, self.iv)
        ciptext = self.iv + cipher.encrypt(data)+self.key
        return ciptext
    # 从mongo取出文件
    def get_file_from_mongo(self,id):
        gf = self.fs_rar.get(ObjectId(id))
        ciptext = gf.read()
        key = ciptext[-16:]
        mydecrypt = AES.new(key, AES.MODE_CFB, ciptext[:16])
        decrytext = mydecrypt.decrypt(ciptext[16:])
        return decrytext

    # 将文件写入硬盘
    def write_to_disk(self, fileName, content):
        with open(fileName, 'wb') as f:
            f.write(content)

if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    print('asdfas')
    root.mainloop()

这是我画UI的网页设计器

Visual TK, Visual Python Tkinter GUI Creatorhttps://www.visualtk.com/下边是ui代码,存为 .bin 文件,可以导入上述页面进行调整。














后续在github更新这里就编辑了 项目名 file2mongdb

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/883691.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号