电子公文传输系统-个人贡献

个人完成的工作

博客的撰写与信息的汇总




后端程序代码的编写

PutinStorage.java

@csrf_exempt
def approveDocument(request):
    current_user = request.session['username']
    if request.method == 'POST':
        data = json.loads(request.body)
        document_name = data.get('documentName')

        # 添加日志打印
        print("Received document_name:", document_name)
        try:
            # 根据 document_id 获取对应的文档
            document = Document.objects.get(document_name=document_name)
            document.is_pass = 1
            document.is_sent = 1

            LogData = Log.objects.create(
                username=current_user,
                documentname=document.document_name,
                operation=f'用户{current_user}于{timezone.now()}通过了公文:{document.document_name}。'
            )
            LogData.save()

            document.save()

            return JsonResponse({'message': 'Document status updated successfully'})
        except Document.DoesNotExist:
            print(f"Document with ID {document_name} does not exist.")
            return JsonResponse({'message': 'Document does not exist'}, status=404)
        except Exception as e:
            print("Error:", e)
            return JsonResponse({'message': 'Internal Server Error'}, status=500)

    return JsonResponse({'message': 'Invalid request'}, status=400)
@csrf_exempt
def rejectDocument(request):
    current_user = request.session['username']
    if request.method == 'POST':
        data = json.loads(request.body)
        document_name = data.get('documentName')
        doc_issuing_office = data.get('issuing_office')

        # 添加日志打印
        print("Received document_name:", document_name)
        print("Received doc_issuing_office:", doc_issuing_office)
        try:
            # 根据 document_id 获取对应的文档
            document = Document.objects.get(document_name=document_name)
            document.is_pass = 0
            document.is_sent = 0
            document.document_owner = document.issuing_office

            LogData = Log.objects.create(
                username=current_user,
                documentname=document.document_name,
                operation=f'用户{current_user}于{timezone.now()}拒绝了公文:{document.document_name}。'
            )
            LogData.save()

            document.save()

            return JsonResponse({'message': 'Document status updated successfully'})
        except Document.DoesNotExist:
            print(f"Document with ID {document_name} does not exist.")
            return JsonResponse({'message': 'Document does not exist'}, status=404)
        except Exception as e:
            print("Error:", e)
            return JsonResponse({'message': 'Internal Server Error'}, status=500)

    return JsonResponse({'message': 'Invalid request'}, status=400)
def decrypt_document(request):
    current_user = request.session['username']
    if request.method == 'POST':
        # 获取传递的文件地址或其他必要信息
        data = json.loads(request.body)
        file_title = data.get('file_title')
        file_name = data.get('file_name')

        print(file_title)
        print(file_name)

        doc = Document.objects.get(document_name=file_title)
        file_path = os.path.join(settings.BASE_DIR, 'web', 'static', 'docx', file_name)
        print(file_path)
        doc_owner = doc.issuing_office
        cc_office = doc.cc_office
        sender_keyowner = UserProfile.objects.get(id=doc_owner)
        sender_publickey = sender_keyowner.public_key
        sender_privatekey = sender_keyowner.private_key
        key_owner = UserProfile.objects.get(username_up=cc_office)
        publickey = key_owner.public_key
        privatekey = key_owner.private_key

        key_sign_path = os.path.join(settings.BASE_DIR, 'web', 'static', 'sign', (file_title + 'signkey.dat'))
        key_encrypt_path = os.path.join(settings.BASE_DIR, 'web', 'static', 'key', (file_title + 'encryptkey.dat'))
        verify_signature(public_key=sender_publickey,
                         private_key=sender_privatekey,
                         input_file=key_encrypt_path,
                         signature_file=key_sign_path)

        key_path = os.path.join(settings.BASE_DIR, 'web', 'static', 'key', (file_title + 'key.dat'))

        decrypt_data(public_key=publickey,
                     private_key=privatekey,
                     input_file=key_encrypt_path,
                     output_file=key_path)

        key = get_or_generate_key(file_title)
        print(f'对称密钥的类型为:{type(key)}')
        # 在这里执行文件解密的操作
        decrypted_file_address = decrypt_and_hash_file(file_path, key, file_title)

        LogData = Log.objects.create(
            username=current_user,
            documentname=doc.document_name,
            operation=f'用户{current_user}于{timezone.now()}下载了公文:{doc.document_name}。'
        )
        LogData.save()

        # 返回解密结果(成功或失败)
        return JsonResponse({'message': '文件解密成功', 'decrypted_file_address': decrypted_file_address})  # 或者其他成功信息
    else:
        return JsonResponse({'message': '无效的请求'}, status=400)
## 密码功能实现
## SM4对称密码算法、SM3哈希摘要算法 ##
def get_or_generate_key(document_name):
    # 尝试从外部输入获取密钥
    key_file_path = os.path.join(settings.BASE_DIR, 'web', 'static', 'key', (document_name + 'key.dat'))
    print(key_file_path)
    if os.path.exists(key_file_path):
        with open(key_file_path, 'rb') as key_file:
            key = key_file.read()
            print(key)
            print(len(key))
            if len(key) != 16:
                print("密钥长度必须为16字节")
                return None
    else:
        # 生成随机的16字节密钥
        key = secrets.token_bytes(16)
        with open(key_file_path, 'wb') as key_file:
            key_file.write(key)

    return key
def encrypt_and_hash_file(input_file_path, key, document_name):
    # 读取文件内容
    with open(input_file_path, 'rb') as file:
        plaintext = file.read()

    # 计算文件的哈希值
    hash_value = sm3_hash(list(plaintext))  # Convert bytes to list
    hash_file_path = os.path.join(settings.BASE_DIR, 'web', 'static', 'secure', (document_name + 'hash_original.dat'))
    with open(hash_file_path, 'w') as hash_file:
        hash_file.write(hash_value)

    print(f'原文件的哈希值已保存到:{hash_file_path}')

    # 初始化SM4加密器
    crypt_sm4 = CryptSM4()

    # 设置密钥
    crypt_sm4.set_key(key, SM4_ENCRYPT)

    # 加密文件内容
    ciphertext = crypt_sm4.crypt_ecb(plaintext)

    # 创建加密后的文件
    encrypted_file_path = os.path.join(settings.BASE_DIR, 'web', 'static', 'docx', (document_name + '.enc'))
    with open(encrypted_file_path, 'wb') as file:
        file.write(ciphertext)

    print(f'文件加密成功:{encrypted_file_path}')
def decrypt_and_hash_file(encrypted_file_path, key, document_name):
    # 初始化SM4解密器
    crypt_sm4 = CryptSM4()

    # 设置密钥
    crypt_sm4.set_key(key, SM4_DECRYPT)

    # 读取加密文件内容
    with open(encrypted_file_path, 'rb') as file:
        ciphertext = file.read()

    # 解密文件内容
    plaintext = crypt_sm4.crypt_ecb(ciphertext)

    # 创建解密后的文件
    decrypted_file_path = os.path.join(settings.BASE_DIR, 'web', 'static', 'docxs', (document_name + '.docx'))
    with open(decrypted_file_path, 'wb') as file:
        file.write(plaintext)

    print(f'文件解密成功:{decrypted_file_path}')

    # 计算解密文件的哈希值
    hash_value = sm3_hash(list(plaintext))  # Convert bytes to list

    # 将哈希值保存到hash_decrypted.txt文件
    hash_decrypted_file_path = os.path.join(settings.BASE_DIR, 'web', 'static', 'secure', (document_name + 'hash_decrypted.dat'))
    with open(hash_decrypted_file_path, 'w') as hash_file:
        hash_file.write(hash_value)

    print(f'解密文件的哈希值已保存到:{hash_decrypted_file_path}')

    # 比较原始哈希和解密后的哈希
    hash_original_file = os.path.join(settings.BASE_DIR, 'web', 'static', 'secure',
                                      (document_name + 'hash_original.dat'))
    hash_decrypted_file = os.path.join(settings.BASE_DIR, 'web', 'static', 'secure',
                                       (document_name + 'hash_decrypted.dat'))

    with open(hash_original_file, 'rb') as original, open(hash_decrypted_file, 'rb') as decrypted:
        original_hash = original.read()
        decrypted_hash = decrypted.read()

        if original_hash == decrypted_hash:
            print("加密和解密后的文件内容一致。")
        else:
            print("加密和解密后的文件内容不一致。")

    decrypted_file_path_str = f'/static/docxs/{document_name}'+'.docx'

    return decrypted_file_path_str
## SM2算法实现 ##
## SM2密钥生成 ##
class CurveFp:
    def __init__(self, A, B, P, N, Gx, Gy, name):
        self.A = A
        self.B = B
        self.P = P
        self.N = N
        self.Gx = Gx
        self.Gy = Gy
        self.name = name


sm2p256v1 = CurveFp(
    name="sm2p256v1",
    A=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC,
    B=0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93,
    P=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF,
    N=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123,
    Gx=0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7,
    Gy=0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0
)


def multiply(a, n, N, A, P):
    return fromJacobian(jacobianMultiply(toJacobian(a), n, N, A, P), P)


def add(a, b, A, P):
    return fromJacobian(jacobianAdd(toJacobian(a), toJacobian(b), A, P), P)


def inv(a, n):
    if a == 0:
        return 0
    lm, hm = 1, 0
    low, high = a % n, n
    while low > 1:
        r = high // low
        nm, new = hm - lm * r, high - low * r
        lm, low, hm, high = nm, new, lm, low
    return lm % n


def toJacobian(Xp_Yp):
    Xp, Yp = Xp_Yp
    return (Xp, Yp, 1)


def fromJacobian(Xp_Yp_Zp, P):
    Xp, Yp, Zp = Xp_Yp_Zp
    z = inv(Zp, P)
    return ((Xp * z ** 2) % P, (Yp * z ** 3) % P)


def jacobianDouble(Xp_Yp_Zp, A, P):
    Xp, Yp, Zp = Xp_Yp_Zp
    if not Yp:
        return (0, 0, 0)
    ysq = (Yp ** 2) % P
    S = (4 * Xp * ysq) % P
    M = (3 * Xp ** 2 + A * Zp ** 4) % P
    nx = (M ** 2 - 2 * S) % P
    ny = (M * (S - nx) - 8 * ysq ** 2) % P
    nz = (2 * Yp * Zp) % P
    return (nx, ny, nz)


def jacobianAdd(Xp_Yp_Zp, Xq_Yq_Zq, A, P):
    Xp, Yp, Zp = Xp_Yp_Zp
    Xq, Yq, Zq = Xq_Yq_Zq
    if not Yp:
        return (Xq, Yq, Zq)
    if not Yq:
        return (Xp, Yp, Zp)
    U1 = (Xp * Zq ** 2) % P
    U2 = (Xq * Zp ** 2) % P
    S1 = (Yp * Zq ** 3) % P
    S2 = (Yq * Zp ** 3) % P
    if U1 == U2:
        if S1 != S2:
            return (0, 0, 1)
        return jacobianDouble((Xp, Yp, Zp), A, P)
    H = U2 - U1
    R = S2 - S1
    H2 = (H * H) % P
    H3 = (H * H2) % P
    U1H2 = (U1 * H2) % P
    nx = (R ** 2 - H3 - 2 * U1H2) % P
    ny = (R * (U1H2 - nx) - S1 * H3) % P
    nz = (H * Zp * Zq) % P
    return (nx, ny, nz)


def jacobianMultiply(Xp_Yp_Zp, n, N, A, P):
    Xp, Yp, Zp = Xp_Yp_Zp
    if Yp == 0 or n == 0:
        return (0, 0, 1)
    if n == 1:
        return (Xp, Yp, Zp)
    if n < 0 or n >= N:
        return jacobianMultiply((Xp, Yp, Zp), n % N, N, A, P)
    if (n % 2) == 0:
        return jacobianDouble(jacobianMultiply((Xp, Yp, Zp), n // 2, N, A, P), A, P)
    if (n % 2) == 1:
        return jacobianAdd(jacobianDouble(jacobianMultiply((Xp, Yp, Zp), n // 2, N, A, P), A, P), (Xp, Yp, Zp), A, P)

class PrivateKey:
    def __init__(self, curve=sm2p256v1, secret=None):
        self.curve = curve
        self.secret = secret or SystemRandom().randrange(1, curve.N)

    def publicKey(self):
        curve = self.curve
        xPublicKey, yPublicKey = multiply((curve.Gx, curve.Gy), self.secret, A=curve.A, P=curve.P, N=curve.N)
        return PublicKey(xPublicKey, yPublicKey, curve)

    def toString(self):
        return "{}".format(str(hex(self.secret))[2:].zfill(64))
class PublicKey:
    def __init__(self, x, y, curve):
        self.x = x
        self.y = y
        self.curve = curve

    def toString(self, compressed=True):
        return {
            True: str(hex(self.x))[2:],
            False: "{}{}".format(str(hex(self.x))[2:].zfill(64), str(hex(self.y))[2:].zfill(64))
        }.get(compressed)
## SM2加解密和签名验签 ##
def encrypt_data(public_key, private_key, input_file, output_file):
    sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)

    with open(input_file, 'rb') as f:
        data = f.read()
    print(public_key)
    print(private_key)
    print(type(public_key))
    print(type(private_key))
    encrypted_data = sm2_crypt.encrypt(data)

    with open(output_file, 'wb') as f:
        f.write(encrypted_data)
def decrypt_data(public_key, private_key, input_file, output_file):
    sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)

    with open(input_file, 'rb') as f:
        encrypted_data = f.read()

    decrypted_data = sm2_crypt.decrypt(encrypted_data)

    with open(output_file, 'wb') as f:
        f.write(decrypted_data)
def sign_data(public_key, private_key, input_file, signature_file):
    sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)

    with open(input_file, 'rb') as f:
        data = f.read()

    random_hex_str = func.random_hex(sm2_crypt.para_len)
    signature = sm2_crypt.sign(data, random_hex_str)

    with open(signature_file, 'wb') as f:
        f.write(binascii.unhexlify(signature))
def verify_signature(public_key, private_key, input_file, signature_file):
    sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)

    with open(input_file, 'rb') as f:
        data = f.read()

    with open(signature_file, 'rb') as f:
        signature = f.read()

    if sm2_crypt.verify(binascii.hexlify(signature).decode(), data):
        print("Signature verification successful")
    else:
        print("Signature verification failed")
def get_user_logs(request):
    current_user = request.session.get('username')
    user = UserProfile.objects.get(username_up=current_user)
    print(user.username_up)

    if user.access_level == 1:  # 管理员权限
        user_logs = Log.objects.filter(documentname="无")  # 获取所有用户日志
        user_logs_data = list(user_logs.values())  # 转换为字典列表
        print(user_logs_data)
        return JsonResponse(user_logs_data, safe=False)

    if user.access_level != 1:
        user_logs = Log.objects.filter(username=user.username_up, documentname="无")
        user_logs_data = list(user_logs.values())  # 转换为字典列表
        print(user_logs_data)
        return JsonResponse(user_logs_data, safe=False)
def get_document_logs(request):
    current_user = request.session.get('username')
    user = UserProfile.objects.get(username_up=current_user)

    if user.access_level == 1:  # 管理员权限
        document_logs = Log.objects.exclude(documentname="无")  # 获取所有公文操作日志
        document_logs_data = list(document_logs.values())  # 转换为字典列表
        print(document_logs_data)
        return JsonResponse(document_logs_data, safe=False)
    if user.access_level != 1:
        document_logs = Log.objects.exclude(documentname="无").filter(username=user.username_up)
        document_logs_data = list(document_logs.values())  # 转换为字典列表
        print(document_logs_data)
        return JsonResponse(document_logs_data, safe=False)
def logout(request):
    current_user = request.session['username']
    # 清除会话信息
    if 'user_id' in request.session:

        LogData = Log.objects.create(
            username=current_user,
            documentname="无",
            operation=f'用户{current_user}于{timezone.now()}退出了系统。'
        )

        LogData.save()

        del request.session['user_id']
        del request.session['username']

    # 重定向到主页或登录页
    return redirect('index')  # 'index' 应该是你的主页 URL 名称或路径
def upload_avatar_page(request):
    # 传递表单给模板,以便在页面上显示上传表单
    form = AvatarUploadForm()
    return render(request, 'upload_avatar.html', {'form': form})
def upload_avatar(request):
    current_user = request.session.get('username')  # 使用 get 方法以避免键不存在时引发 KeyError
    if request.method == 'POST':
        form = AvatarUploadForm(request.POST, request.FILES)
        if form.is_valid():
            try:
                user_profile = UserProfile.objects.get(username_up=current_user)
                avatar_image = form.cleaned_data['avatarFile']
                image = Image.open(avatar_image)
                # 将图像转换为PNG格式并覆盖原始图像文件
                image = image.convert("RGB")
                image.save(user_profile.avatar.path, 'JPEG')
                user_profile.save()
                return redirect('index')  # 重定向到首页或其他页面
            except UserProfile.DoesNotExist:
                # 处理用户不存在的情况
                pass
    else:
        form = AvatarUploadForm()

    return render(request, 'upload_avatar.html', {'form': form})

上传代码至gitee

代码链接

分配一些工作

小组代码总行数

  • 3500行

我贡献的代码行数

  • 500行

小组总文档数

  • 11

我贡献的文档数

  • 7

链接

团队展示:
需求分析:
确定分工:
描述设计:
团队作业(五):冲刺总结3
团队作业(五):冲刺总结2

posted @ 2023-12-10 12:26  20211428谷丰宇  阅读(11)  评论(0编辑  收藏  举报