解决Python密码管理器中的Padding错误

霞舞
发布: 2025-11-24 11:23:02
原创
115人浏览过

解决python密码管理器中的padding错误

本文旨在解决在使用Python开发密码管理器时遇到的Padding错误问题。该错误通常出现在使用AES加密算法时,由于数据块大小的限制,需要对数据进行填充。本文将提供一个修复后的代码示例,并解释如何正确地进行加密和解密操作,以避免Padding错误,从而安全地存储和检索密码。

在开发密码管理器时,安全性至关重要。使用AES(Advanced Encryption Standard)算法对密码进行加密是一种常见的做法。然而,在使用AES时,开发者经常会遇到“Padding is incorrect”的错误。本文将深入探讨这个问题,并提供一个可靠的解决方案。

问题分析

AES算法要求加密的数据长度必须是块大小的整数倍。如果原始数据长度不是块大小的整数倍,就需要进行填充(Padding)。在解密时,需要去除填充,才能恢复原始数据。ValueError: Padding is incorrect. 错误通常发生在解密阶段,表明填充不正确,导致无法正确解密数据。

解决方案

以下代码展示了一种避免Padding错误的实现方式,它使用了自定义的Padding和Unpadding方法,并使用 hashlib 来处理密钥:

绘蛙AI修图
绘蛙AI修图

绘蛙平台AI修图工具,支持手脚修复、商品重绘、AI扩图、AI换色

绘蛙AI修图 279
查看详情 绘蛙AI修图

立即学习Python免费学习笔记(深入)”;

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))
登录后复制

代码解释:

  1. AESCipher 类: 封装了AES加密和解密操作。
  2. __init__(self, key): 构造函数,接收密钥并使用SHA256算法对其进行哈希处理,以确保密钥的安全性。
  3. encrypt_data(self, iv, raw): 加密数据。首先,使用_pad方法对原始数据进行填充,然后使用AES算法进行加密。
  4. decrypt_data(self, iv, enc): 解密数据。使用AES算法进行解密,然后使用_unpad方法去除填充。
  5. _pad(self, s): 自定义的填充方法。它将原始数据填充到块大小的整数倍。
  6. _unpad(self, s): 自定义的去除填充方法。它去除_pad方法添加的填充。
  7. 密钥处理: 使用 hashlib.sha256(key).digest() 对密钥进行哈希处理,增强安全性。
  8. IV处理: 在加密时,将IV与加密后的数据连接起来,并在解密时将其分离。

注意事项

  • 密钥安全: 请务必安全地存储密钥。如果密钥丢失,将无法解密数据。
  • IV (Initialization Vector) 的使用: 每次加密都应使用不同的IV。IV不需要保密,但必须在解密时使用相同的IV。
  • 文件路径: 避免在代码中硬编码文件路径,特别是包含个人信息的路径。

总结

通过使用自定义的Padding和Unpadding方法,可以有效地避免Python密码管理器中常见的Padding错误。同时,请务必注意密钥的安全存储和IV的正确使用,以确保密码管理器的安全性。记住,安全性是密码管理器开发中最重要的考虑因素。

以上就是解决Python密码管理器中的Padding错误的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号