You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.6 KiB
80 lines
2.6 KiB
4 months ago
|
import base64
|
||
3 months ago
|
import logging
|
||
|
import os.path
|
||
3 months ago
|
|
||
4 months ago
|
from config import config
|
||
4 months ago
|
from entity.Letter import Letter
|
||
3 months ago
|
from tool import PriKeyHelper, DownloadPathTool
|
||
4 months ago
|
from tool.asymmetric import RSA
|
||
3 months ago
|
from tool.hash import Segwit
|
||
3 months ago
|
from tool.symmetric import SM4, AES
|
||
4 months ago
|
|
||
4 months ago
|
|
||
|
def getLetter():
|
||
|
# 阻塞自身 从指定端口获取信件
|
||
|
#
|
||
|
# 解析信件
|
||
|
letter = None
|
||
|
handleLetter(letter)
|
||
|
pass
|
||
|
|
||
3 months ago
|
|
||
|
def handleLetter(letter: Letter):
|
||
4 months ago
|
# 解析信件 确认收信人
|
||
|
# 获取自身key
|
||
|
pki = PriKeyHelper.getUserKey()
|
||
3 months ago
|
print("pki is: ",pki[1])
|
||
|
print("letter.recvPubKey is: ",letter.recvPubKey)
|
||
4 months ago
|
if pki[1] != letter.recvPubKey:
|
||
|
raise Exception("信件不属于自己")
|
||
|
# 用自己的私钥解密key 获得对称加密秘钥。
|
||
3 months ago
|
key = RSA.decrypt_message(base64.b64decode(letter.encryptKey), pki[0])
|
||
4 months ago
|
|
||
|
# 根据不同的对称加密算法
|
||
|
try:
|
||
|
type = config.getEncryptType(letter.encryptType)
|
||
4 months ago
|
except ValueError:
|
||
|
raise ValueError("不支持的对称加密算法")
|
||
4 months ago
|
# 进行解密fileBase64
|
||
4 months ago
|
data = b""
|
||
4 months ago
|
if type == config.EncryptType.SM4_ECB:
|
||
3 months ago
|
data = base64.b64decode(SM4.decrypt_ecb(letter.fileBase64, key))
|
||
4 months ago
|
elif type == config.EncryptType.SM4_CBC:
|
||
3 months ago
|
data = base64.b64decode(SM4.decrypt_cbc_with_iv(letter.fileBase64, key))
|
||
4 months ago
|
elif type == config.EncryptType.AES_ECB:
|
||
3 months ago
|
data = base64.b64decode(AES.AESUtils().decrypt(key, letter.fileBase64, "ecb"))
|
||
4 months ago
|
elif type == config.EncryptType.AES_CBC:
|
||
3 months ago
|
data = base64.b64decode(AES.AESUtils().decrypt(key, letter.fileBase64,"cbc"))
|
||
4 months ago
|
else:
|
||
|
raise KeyError("不支持的对称加密算法")
|
||
|
|
||
|
# 用发信人的公钥验签摘要
|
||
3 months ago
|
result = RSA.verify_signature(data, letter.sign, letter.senderPubKey)
|
||
4 months ago
|
if not result:
|
||
|
raise Exception("签名验证失败,文件不可信")
|
||
|
|
||
|
# 保存文件
|
||
3 months ago
|
|
||
|
# 默认下载目录
|
||
|
download_dir = DownloadPathTool.get_download_directory()
|
||
3 months ago
|
filename = letter.fileName
|
||
|
base_name, ext = os.path.splitext(filename) # 分离文件名和扩展名
|
||
|
newName = None
|
||
|
count = 0
|
||
|
while True:
|
||
|
if count:
|
||
|
newName = f"{base_name}({count}){ext}"
|
||
|
else:
|
||
|
newName = filename
|
||
|
path = f"{download_dir}/{newName}"
|
||
|
if os.path.exists(path):
|
||
|
logging.debug("文件已存在,自动避免覆盖写入")
|
||
|
count += 1
|
||
|
else:
|
||
|
break
|
||
|
with open(path, "wb") as f:
|
||
4 months ago
|
f.write(data)
|
||
3 months ago
|
print(f"确认收到来自 {Segwit.encodeSegwit(letter.senderPubKey.encode('utf-8'))} 的文件")
|
||
3 months ago
|
print(f"签名验证有效,已将文件 {newName} 保存至 {download_dir} 下")
|
||
3 months ago
|
return
|