Skip to content
This repository was archived by the owner on Mar 20, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
.idea/
__pycache__/
config.py
forms/__pycache__/
instance
templates/login/debug.log
templates/upload/debug.log
static/secret/
example.db
110 changes: 101 additions & 9 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,83 @@
from flask import Flask, request
import mail
import file
from flask import render_template, redirect, url_for, request
from forms.signin_form import LoginForm
from forms.signup_form import RegisterForm
from forms.dowmload_form import DownloadForm
from flask_wtf.csrf import CSRFProtect, CSRFError
from flask_login import LoginManager, login_required, login_user, logout_user,current_user
import config

app = Flask(__name__)
from database import create_app, add_user
from models import User
import signinup

app = create_app()
# 防止跨站脚本攻击
app.secret_key = config.secretinfo['secret_key']
app.config['MAX_CONTENT_LENGTH'] = 20 * 1024 * 1024 # 20MB
# app.config['WTF_CSRF_SECRET_KEY'] = 'CSRFTokenGeneratorSecretKey2018' # CSRF Token生成器的签发密钥
# app.config['WTF_CSRF_TIME_LIMIT'] = 10 # 表单提交限时1分钟,超时则触发CSRF Token校验失败错误
csrf = CSRFProtect(app)

# Add LoginManager
login_manager = LoginManager()
login_manager.session_protection = config.secretinfo['login_manager_session_protection']
login_manager.login_view = config.secretinfo['login_manager_login_view']
login_manager.login_message = config.secretinfo['login_manager_login_message']
login_manager.login_message_category = config.secretinfo['login_manager_login_message_category']
login_manager.init_app(app)

@login_manager.user_loader
def load_user(userid):
#return User.query.get(int(userid))
return User.query.filter_by(id=userid).first()


@app.route('/')
def index():
return render_template('index.html')


# ------------------------------------------------------退出登录部分代码----------------------------
@app.route('/signoff')
@login_required
def signoff():
logout_user()
return redirect(url_for('index'))


# ----------------------------------------------------注册部分的代码-----------------------------------
@app.route('/signin', methods=['GET'])
def signin():
form = LoginForm()
return render_template('./login/signup.html', form=form)


@app.route('/signin', methods=['POST'])
def do_signin():
html = signinup.signin_User()
return html


# --------------------------------------------登陆部分的代码-------------------------------------------
@app.route('/signup', methods=['GET'])
def signup():
form = RegisterForm()
return render_template('./login/signin.html', form=form)


@app.route('/signup', methods=['POST'])
def do_signup():
html = signinup.signup_User()
return html


@csrf.exempt
@app.errorhandler(CSRFError)
def handle_csrf_error(e):
return render_template('./csrf/csrf_error.html', reason=e.description), 400


@app.route('/test_mail')
Expand All @@ -11,21 +86,38 @@ def test_mail():
return mail.test_mail(email)


@app.route('/upload_file', methods=['POST'])
@app.route('/upload_file', methods=['GET', 'POST'])
@login_required
def upload_file():
# f = 要上传的文件
# file.upload_file(f)
pass
print(current_user.is_anonymous)
f=file.upload_file()
return f


# 文件下载页面
@app.route('/filedownload', methods=['GET'])
def filedownload():
form = DownloadForm()
return render_template('./upload/download.html',form=form)

@app.route('/filelist', methods=['GET','POST'])
def filelist():
filelist = file.file_list()
return filelist

@app.route('/file_list')
def file_list():
file.file_list()
pass

@app.route('/download', methods=['GET', 'POST'])
def download():
form = DownloadForm()
filename = form.filename.data
print(current_user.is_authenticated)
if current_user.is_authenticated:
return file.download(filename)
return file.download_anonmity(filename)

def main():
mail.init(app)
file.init(app)
app.run(host='zlbweb.cn', port=443, ssl_context=('cert.pem', 'key.pem'))


Expand Down
33 changes: 33 additions & 0 deletions database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

import config

db = SQLAlchemy()


def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = config.secretinfo['SQLALCHEMY_DATABASE_URI']
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = config.secretinfo['SQLALCHEMY_TRACK_MODIFICATIONS']
db.init_app(app)

with app.app_context():
from models import User
db.create_all()
# db.session.merge(User(id=0, username="lycheng", email='anjing@cuc.edu.cn', password='aB8'))
db.session.commit()

return app


def add_user(user, userID):
from models import User
db.session.add(User(id=userID, username=user.userName.data, email=user.email.data, password=user.password.data, salt=user.salt.encode()))
db.session.commit()


def add_filehash(pfilename, phash):
from models import FileHash
db.session.merge(FileHash(filename=pfilename, hash=phash))
db.session.commit()
186 changes: 186 additions & 0 deletions encryption.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import sys
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import rsa
import os


class prpcrypt():
def __init__(self, key):
self.key = key
self.mode = AES.MODE_CBC

# 加密函数,如果text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数
def encrypt(self, text):
cryptor = AES.new(self.key, self.mode, self.key)

length = 16
count = len(text)
if (count % length != 0):
add = length - (count % length)
else:
add = 0
text = text + ('\0' * add).encode()
self.ciphertext = cryptor.encrypt(text)
# 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
# 所以这里统一把加密后的字符串转化为16进制字符串
return b2a_hex(self.ciphertext)

# 解密后,去掉补足的空格用strip() 去掉
def decrypt(self, text):
cryptor = AES.new(self.key, self.mode, self.key)
plain_text = cryptor.decrypt(a2b_hex(text))
return plain_text.rstrip(('\0').encode())


def encryption_file(filedata):
with open('./static/secret/publickey.txt', 'rb') as f: # 以二进制写类型打开
publicKey = (f.read()).decode()

# 将获取得到的字符串转化为公钥所需参数(n,e)
para1 = publicKey[10:-8]
para2 = publicKey[-6:-1]

# 公钥初始化
publicKey = rsa.key.PublicKey(int(para1), int(para2))

with open('./static/secret/privatekey.txt', 'rb') as f: # 以二进制写类型打开
privateKey = (f.read()).decode()

# 解析字符串转换为私钥所需的五个参数(n,e,d,p,q)
para3 = privateKey[len(para1) + len(para2) + 15:-1]
para4 = para3[:-908]
para3 = para3[-906:]
para3, para4 = para4, para3
para5 = para4[:480]
para4 = para4[482:]
para4, para5 = para5, para4

# 私钥初始化
privateKey = rsa.key.PrivateKey(int(para1), int(para2), int(para3), int(para4), int(para5))

# 获得对称密钥
with open('./static/secret/symmetrickey.txt', 'rb') as f: # 以二进制写类型打开
secretkey = f.read()
message = rsa.decrypt(secretkey, privateKey)

# 采用AES_CBC模式加密
secretkey = message
pc = prpcrypt(secretkey) # 初始化密钥

# 加密操作
return pc.encrypt(filedata)


def decryption_file(filedata):
with open('./static/secret/publickey.txt', 'rb') as f: # 以二进制写类型打开
publicKey = (f.read()).decode()

# 将获取得到的字符串转化为公钥所需参数(n,e)
para1 = publicKey[10:-8]
para2 = publicKey[-6:-1]

# 公钥初始化
publicKey = rsa.key.PublicKey(int(para1), int(para2))

with open('./static/secret/privatekey.txt', 'rb') as f: # 以二进制写类型打开
privateKey = (f.read()).decode()

# 解析字符串转换为私钥所需的五个参数(n,e,d,p,q)
para3 = privateKey[len(para1) + len(para2) + 15:-1]
para4 = para3[:-908]
para3 = para3[-906:]
para3, para4 = para4, para3
para5 = para4[:480]
para4 = para4[482:]
para4, para5 = para5, para4

# 私钥初始化
privateKey = rsa.key.PrivateKey(int(para1), int(para2), int(para3), int(para4), int(para5))

# 获得对称密钥
with open('./static/secret/symmetrickey.txt', 'rb') as f: # 以二进制写类型打开
secretkey = f.read()
message = rsa.decrypt(secretkey, privateKey)

# 采用AES_CBC模式加密
secretkey = message
pc = prpcrypt(secretkey) # 初始化密钥

# 解密操作
with open(filedata, 'rb') as file:
d = pc.decrypt(file.read())
return d


# 对加密后的数据进行签名,参数为已经加密但未签名的文件
def sign_file(filedata):
with open('./static/secret/publickey.txt', 'rb') as f: # 以二进制写类型打开
publicKey = (f.read()).decode()

# 将获取得到的字符串转化为公钥所需参数(n,e)
para1 = publicKey[10:-8]
para2 = publicKey[-6:-1]

# 公钥初始化
publicKey = rsa.key.PublicKey(int(para1), int(para2))

with open('./static/secret/privatekey.txt', 'rb') as f: # 以二进制写类型打开
privateKey = (f.read()).decode()

# 解析字符串转换为私钥所需的五个参数(n,e,d,p,q)
para3 = privateKey[len(para1) + len(para2) + 15:-1]
para4 = para3[:-908]
para3 = para3[-906:]
para3, para4 = para4, para3
para5 = para4[:480]
para4 = para4[482:]
para4, para5 = para5, para4

# 私钥初始化
privateKey = rsa.key.PrivateKey(int(para1), int(para2), int(para3), int(para4), int(para5))

# 获得对称密钥
with open('./static/secret/symmetrickey.txt', 'rb') as f: # 以二进制写类型打开
secretkey = f.read()
message = rsa.decrypt(secretkey, privateKey)

# 采用AES_CBC模式加密
# secretkey = message
# pc = prpcrypt(secretkey) # 初始化密钥

# 使用对称密钥加密数据
# endata = pc.encrypt(filedata)
print('filedata=',len(filedata))
print('endata=',len(filedata))
# 对加密的数据进行签名
return rsa.sign(filedata, privateKey, 'SHA-1')


# 验证签名,参数为签名后的文件和未签名的文件
def verify_file(signfile, filedata):
with open('./static/secret/publickey.txt', 'rb') as f: # 以二进制写类型打开
publicKey = (f.read()).decode()

# 将获取得到的字符串转化为公钥所需参数(n,e)
para1 = publicKey[10:-8]
para2 = publicKey[-6:-1]

# 公钥初始化
publicKey = rsa.key.PublicKey(int(para1), int(para2))

with open('./static/secret/privatekey.txt', 'rb') as f: # 以二进制写类型打开
privateKey = (f.read()).decode()

# 解析字符串转换为私钥所需的五个参数(n,e,d,p,q)
para3 = privateKey[len(para1) + len(para2) + 15:-1]
para4 = para3[:-908]
para3 = para3[-906:]
para3, para4 = para4, para3
para5 = para4[:480]
para4 = para4[482:]
para4, para5 = para5, para4

# 私钥初始化
privateKey = rsa.key.PrivateKey(int(para1), int(para2), int(para3), int(para4), int(para5))
return rsa.verify(filedata, signfile, publicKey)
Loading