这个错误翻译过来就是:ValueError:数据必须在 CBC 模式下填充到 16 字节边界

其实报错信息已经很明显了,大概意思就是数据长度不是16的倍数


我爬取了很多ts文件,但这些文件是经过加密的,我准备进行解密,下面是解密代码:

# 解密操作
def decrypt(key, encrypted_ts_directory, decrypt_ts_directory):
    # AES对象,传入密钥,偏移量,模式
    # key必须为字节
    aes = AES.new(key=key.encode('utf-8'), IV=b'0000000000000000', mode=AES.MODE_CBC)
    # 获取文件或目录列表(返回的list的顺序跟我们想要的不一样)
    ts_all = os.listdir(encrypted_ts_directory)
    # 对列表进行排序,倒着数第3位'.'为分界线,按照‘.'左边的数字从小到大排序
    ts_all.sort(key=lambda x: int(x[:-3]))
    for ts in ts_all:
        with open(file=encrypted_ts_directory + f'/{ts}', mode='rb') as fr:
            with open(file=decrypt_ts_directory + f'/{ts}', mode='wb') as fw:
                # 从加密的文件夹中读取文件
                encrypted_data = fr.read()
                # 进行解密
                decrypt_data = aes.decrypt(encrypted_data)
                # 将解密后的数据写入对应的解密文件
                fw.write(decrypt_data)
    print('解密成功!')

但在运行的时候报了这个错误

在网上找解决办法的时候,发现很多人都说要添加IV=b'0000000000000000'这么个东西,还得保证后面的0是16个。我当时就在想,我明明有IV啊,难道是0没有16个吗?我还特意去数了,发现没有少。正当我百思不得其解的时候,不小心撇了一眼报错,然后

我发现大佬们的错误信息跟我的不一样,他们的错误是ValueError: IV must be 16 bytes long

唉,我这个眼睛啊,关顾着看16这个数字去了


那么怎么解决呢?

到底是不是因为长度不是16的倍数呢,试试就知道了

# 解密操作
def decrypt(key, encrypted_ts_directory, decrypt_ts_directory):
    # AES对象,传入密钥,偏移量,模式
    # key必须为字节
    aes = AES.new(key=key.encode('utf-8'), IV=b'0000000000000000', mode=AES.MODE_CBC)
    # 获取文件或目录列表(返回的list的顺序跟我们想要的不一样)
    ts_all = os.listdir(encrypted_ts_directory)
    # 对列表进行排序,倒着数第3位'.'为分界线,按照‘.'左边的数字从小到大排序
    ts_all.sort(key=lambda x: int(x[:-3]))
    for ts in ts_all:
        with open(file=encrypted_ts_directory + f'/{ts}', mode='rb') as fr:
            with open(file=decrypt_ts_directory + f'/{ts}', mode='wb') as fw:
                # 从加密的文件夹中读取文件
                encrypted_data = fr.read()
                # 获取长度
                encrypted_data_len = len(encrypted_data)
                # 判断当前的数据长度是不是16的倍数
                if encrypted_data_len % 16 != 0:
                    # 把长度不是16的倍数的显示出来
                    print(encrypted_data_len)
                # 进行解密
                # decrypt_data = aes.decrypt(encrypted_data)
                # 将解密后的数据写入对应的解密文件
                # fw.write(decrypt_data)
    # print('解密成功!')

结果一看

 还真有!

欧克,那么我们开始解决吧,长度不是16的倍数,那就让它变成16的倍数不就好了

# 对应的模块
from Crypto.Util.Padding import pad

# 变为16的倍数
encrypted_data = pad(encrypted_data, 16)

 最终的代码长这样

# 解密操作
def decrypt(key, encrypted_ts_directory, decrypt_ts_directory):
    # AES对象,传入密钥,偏移量,模式
    # key必须为字节
    aes = AES.new(key=key.encode('utf-8'), IV=b'0000000000000000', mode=AES.MODE_CBC)
    # 获取文件或目录列表(返回的list的顺序跟我们想要的不一样)
    ts_all = os.listdir(encrypted_ts_directory)
    # 对列表进行排序,倒着数第3位'.'为分界线,按照‘.'左边的数字从小到大排序
    ts_all.sort(key=lambda x: int(x[:-3]))
    for ts in ts_all:
        with open(file=encrypted_ts_directory + f'/{ts}', mode='rb') as fr:
            with open(file=decrypt_ts_directory + f'/{ts}', mode='wb') as fw:
                # 从加密的文件夹中读取文件
                encrypted_data = fr.read()
                # 获取长度
                encrypted_data_len = len(encrypted_data)
                # 判断当前的数据长度是不是16的倍数
                if encrypted_data_len % 16 != 0:
                    # 把长度不是16的倍数的显示出来
                    # print(encrypted_data_len)
                    # 变为16的倍数
                    encrypted_data = pad(encrypted_data, 16)
                # 进行解密
                decrypt_data = aes.decrypt(encrypted_data)
                # 将解密后的数据写入对应的解密文件
                fw.write(decrypt_data)
    print('解密成功!')

 结果没有报错

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐