当前位置:

首页 > 编程开发 > 密码管理器Padding问题怎么解决

密码管理器Padding问题怎么解决

本文旨在解决在使用Python的Crypto库进行AES加密时,由于Padding不正确导致的解密失败问题。通过引入自定义的Padding和Unpadding方法,并结合示例代码,详细展示了如何正确地加密和解密密码,并将其安全地存储在文本文件中。同时,也对代码结构和潜在的安全风险提出了改进建议,确保密码管理器的安全性和可靠性。

本文目录

    解决密码管理器中的Padding问题

    本文旨在解决在使用Python的`Crypto`库进行AES加密时,由于Padding不正确导致的解密失败问题。通过引入自定义的Padding和Unpadding方法,并结合示例代码,详细展示了如何正确地加密和解密密码,并将其安全地存储在文本文件中。同时,也对代码结构和潜在的安全风险提出了改进建议,确保密码管理器的安全性和可靠性。

    在使用 Crypto 库进行 AES 加密时,Padding 错误是一个常见的问题,尤其是在处理需要多次加密和解密,并将结果保存到文件中的场景下。 根本原因是AES算法要求加密的数据长度必须是块大小(通常是16字节)的倍数。当数据长度不满足此要求时,需要进行 Padding 填充。如果 Padding 的方式不正确,解密时就会出现 ValueError: Padding is incorrect. 错误。

    理解Padding和Unpadding

    Padding 是在数据末尾添加额外字节,使其长度达到块大小的倍数的过程。Unpadding 则是解密后,移除这些额外字节,恢复原始数据的过程。Crypto.Util.Padding 模块提供了一些 Padding 和 Unpadding 的方法,但有时使用自定义的方法可能更可靠。

    解决Padding问题的示例代码

    以下代码展示了如何使用自定义的 Padding 和 Unpadding 方法来解决这个问题。此代码基于 Stack Overflow 上的一个答案,并进行了修改以适应密码管理器的需求。

    import re
    import random
    import string
    from Crypto.Cipher import AES
    from Crypto.Random import get_random_bytes
    import hashlib
    
    def password_generator(size=10):
        if size <= 8:
            print("Size must be at least 4")
            return None
        password = []
        while len(password) < size:
            password.append(random.choice(string.ascii_lowercase))  # ensure at least one lowercase letter
            if len(password) < size:
                password.append(random.choice(string.ascii_uppercase))  # ensure at least one uppercase letter
            if len(password) < size:
                password.append(random.choice(string.digits))  # ensure at least one digit
            if len(password) < size:
                password.append(random.choice(string.punctuation))  # ensure at least one special character
        random.shuffle(password)  # shuffle to remove the predictability
        return ''.join(password)
    
    def password_checker(password):
        if len(password) >= 8:
            if bool(re.match(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z\d])', password)):
                print("The password is strong")
            else:
                print("The password is weak")
        else:
            print("You have entered a short or invalid password.")
    
    # Generate a password
    generated_password = password_generator()
    print(generated_password)
    
    # Check the generated password
    password_checker(generated_password)
    
    
    class AESCipher(object):
    
        def __init__(self, key):
            self.bs = AES.block_size
            self.key = hashlib.sha256(key).digest()
    
        def encrypt_data(self, iv, raw):
            raw = self._pad(raw)
            cipher = AES.new(self.key, AES.MODE_CBC, iv)
            return cipher.iv, iv + cipher.encrypt(raw.encode())
    
        def decrypt_data(self, iv, enc):
            cipher = AES.new(self.key, AES.MODE_CBC, iv)
            return AESCipher._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')
    
        def _pad(self, s):
            return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)
    
        @staticmethod
        def _unpad(s):
            return s[:-ord(s[len(s)-1:])]
    
    # Generate a random 128-bit IV for AES
    iv = get_random_bytes(16)
    
    # Generate a random 256-bit key for AES
    key = get_random_bytes(32)  # save this maybe?
    
    Cipher = AESCipher(key)
    
    # Encrypt the generated password
    iv, encrypted_password = Cipher.encrypt_data(iv, generated_password)
    print(f"Encrypted password: {encrypted_password}")
    
    # Decrypt the encrypted password
    decrypted_password = Cipher.decrypt_data(iv, encrypted_password)
    print(f"Decrypted password: {decrypted_password}")
    
    # Save the encrypted password to a file
    with open(
            'Password.txt',
            'a', encoding='utf-8') as f:
        f.write(f"{iv.hex()}:{encrypted_password.hex()}\n")
    
    # Read the encrypted password from the file
    with open(
            'Password.txt',
            'r', encoding='utf-8') as f:
        for line in f.readlines():
            line = line.strip()  # Remove the trailing newline character
            iv, encrypted_password = line.split(':')
            decrypted_password = Cipher.decrypt_data(bytes.fromhex(iv), bytes.fromhex(encrypted_password))
            print(f"Decrypted password from file: {decrypted_password}")

    代码解释:

    1. AESCipher 类: 这个类封装了 AES 加密和解密的所有操作,包括初始化、Padding 和 Unpadding。
      • __init__: 初始化方法,接收一个密钥,并使用 SHA256 对其进行哈希处理,以确保密钥的安全性。
      • encrypt_data: 加密数据的方法,先对数据进行 Padding,然后使用 AES 加密。
      • decrypt_data: 解密数据的方法,先使用 AES 解密,然后进行 Unpadding。
      • _pad: 自定义的 Padding 方法,将数据填充到块大小的倍数。
      • _unpad: 自定义的 Unpadding 方法,移除 Padding 字节。
    2. 密钥生成: 使用 get_random_bytes(32) 生成一个 256 位的随机密钥。请注意,在实际应用中,需要安全地存储和管理这个密钥。
    3. 加密和解密流程: 首先创建一个 AESCipher 实例,然后使用 encrypt_data 方法加密密码,并使用 decrypt_data 方法解密密码。
    4. 文件存储: 将 IV 和加密后的密码以十六进制字符串的形式存储在文本文件中,用冒号分隔。读取文件时,将十六进制字符串转换回字节,然后进行解密。

    注意事项和改进建议

    • 密钥管理: 密钥的安全存储至关重要。不要将密钥硬编码在代码中,也不要将其存储在与加密数据相同的文件中。考虑使用密钥管理系统或硬件安全模块 (HSM) 来安全地存储密钥。
    • 避免硬编码路径: 避免在代码中硬编码文件路径,使用相对路径或配置文件来提高代码的可移植性和安全性。
    • 异常处理: 在文件读写和加密解密过程中,添加适当的异常处理,以提高代码的健壮性。
    • 使用更安全的文件格式: 虽然文本文件可以用于存储加密数据,但使用二进制文件格式(如 .bin)可能更安全,因为它们不容易被意外编辑或损坏。
    • 使用更强的密钥派生函数 (KDF): SHA256 是一种哈希函数,但它不是专门为密钥派生设计的。考虑使用 Argon2、bcrypt 或 scrypt 等 KDF 来从用户密码派生密钥。
    • 组织代码结构: 始终将所有导入放在文件的开头,这是一种良好的编码实践。

    总结

    通过使用自定义的 Padding 和 Unpadding 方法,可以有效地解决 Crypto 库中由于 Padding 不正确导致的解密失败问题。同时,注意密钥的安全存储和管理,以及代码的健壮性和安全性,可以构建一个安全可靠的密码管理器。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    GitHub Copilot模型停用后会自动替换吗,哪些事情仍需提前确认?
    GitHub Copilot模型停用后会自动替换吗,哪些事情仍需提前确认?

    Copilot停用旧模型不等于自动迁移;区分移除、组织模型启用、工作流切换与个人年订阅例外。

    GitHub Actions重跑失败作业会使用最新代码吗
    GitHub Actions重跑失败作业会使用最新代码吗

    解释已有运行重跑的提交和权限边界,给出确认、失败作业重跑及结果核对命令,区分漏触发事件。

    chat-demo v0.1.1怎么本地运行并理解DeepSeek历史数据边界
    chat-demo v0.1.1怎么本地运行并理解DeepSeek历史数据边界

    chat-demo v0.1.1可以作为静态聊天客户端在本地运行,但模型、搜索、文件和语音能力仍由DeepSeek API提供。源码运行环境为Node.js 22.12及以上、Git与pnpm。Demo版本号不等于应用API版本;这套应用API未单独标版本,默认聊天模型ID是deepseek-flash。

    GitHub Copilot CLI v1.0.111的用量图与上下文比例应该怎样理解
    GitHub Copilot CLI v1.0.111的用量图与上下文比例应该怎样理解

    理解GitHub Copilot CLI v1.0.111的高级请求百分比、用户提示活动图与实际路由模型窗口,区分显示口径和任务状态。

    n8n 2.47.6、2.47.7、2.48.3 Beta、2.48.4 Beta、3.2.2预发布与1.123.96适用哪些安全修复?
    n8n 2.47.6、2.47.7、2.48.3 Beta、2.48.4 Beta、3.2.2预发布与1.123.96适用哪些安全修复?

    按维护分支、利用权限与节点类型对应四项修复,区分正式补丁、Beta和临时缓解的适用边界。

    GitHub合并故障的已缓解、监控与已解决有什么不同
    GitHub合并故障的已缓解、监控与已解决有什么不同

    GitHub合并故障中的“已缓解并监控”和“已解决”不能互换。前者表示影响已经采取措施缓解,仍在观察稳定性;后者是供应商正式结束这场事故的状态。11月13日的Pull Requests合并超时事件先进入监控,随后于北京时间11月14日02:29标记为已解决。

    llama.cpp v1.0.0的网页聊天分组与Markdown编辑适合哪些场景
    llama.cpp v1.0.0的网页聊天分组与Markdown编辑适合哪些场景

    llama.cpp v1.0.0改善聊天组织、长消息编辑和附件预览;界面变化与底层API迁移、缓存及访问边界需要分别理解。

    Postman 12.36.4 更新后仍报错,怎么判断是哪一层的问题
    Postman 12.36.4 更新后仍报错,怎么判断是哪一层的问题

    Postman 12.36.4 更新后仍有异常时,可按应用、API请求和平台服务区分问题范围,避免把补丁版本当作故障原因。

    n8n 2.47.6、2.48.3 Beta与1.123.96适合哪些部署环境?
    n8n 2.47.6、2.48.3 Beta与1.123.96适合哪些部署环境?

    按正式、预发布和1.x维护渠道对应补丁,再结合Redis、Agent端点和Pinecone索引判断适用范围。

    Codex CLI 0.169.0与0.171.0-alpha.2怎样选择,终端工作区适合哪些任务
    Codex CLI 0.169.0与0.171.0-alpha.2怎样选择,终端工作区适合哪些任务

    Codex CLI 0.169.0提供有明确说明的终端工作区能力;0.171.0-alpha.2为预发布,当前没有功能清单,选用时应分开评估。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。