padding方法

VALID:如果卷积核超出特征层,就不再就计算,即卷积核右边界不超出Feature。如下图,卷积核F移动2次,从左往右第3个长方形的右边界在W内部。

SAME:只要卷积核还覆盖着部分特征层W,就继续计算,即卷积核右边界可以超出Feature,卷积核超出Feature时,Feature补0,实际计算时,Feature会把需要补充的0在W两边平均分配,而不是只补在右边。如下图,卷积核F移动3次,从左往右第4个长方形的左边界在W内部。

VALID中的(-F+1)相当于F与W都减去尾巴。

加0填充可以在VALID的基础上计算,加n列,分母就加n。

<think>我们正在讨论cryptography库中的padding方法。根据引用[2],我们了解到几种常见的填充方式:PKCS#7、位填充、字节填充、零填充等。在cryptography库中,我们主要使用PKCS#7填充。 在cryptography库中,对称加密(如AES)通常使用`cryptography.hazmat.primitives.padding`模块来实现填充。其中,最常用的是PKCS7填充。 下面我们将详细说明如何使用cryptography库中的PKCS7填充。 ### 步骤1:导入必要的模块 ```python from cryptography.hazmat.primitives import padding ``` ### 步骤2:创建填充器 对于加密,我们需要创建一个填充器,指定块大小(例如AES的块大小为128位,即16字节): ```python # 创建一个PKCS7填充器,块大小为128位(16字节) padder = padding.PKCS7(128).padder() ``` ### 步骤3:更新数据并完成填充 将要加密的数据传递给填充器的`update()`方法,然后调用`finalize()`方法完成填充: ```python # 原始数据(必须是字节类型) data = b"Hello, World!" # 更新数据 padded_data = padder.update(data) + padder.finalize() ``` ### 步骤4:创建解填充器 解密后,我们需要使用相同的填充方案来移除填充: ```python # 创建一个PKCS7解填充器,块大小同样为128位 unpadder = padding.PKCS7(128).unpadder() # 更新数据并移除填充 unpadded_data = unpadder.update(padded_data) + unpadder.finalize() ``` ### 完整示例 以下是一个完整的示例,展示如何使用PKCS7填充和解填充: ```python from cryptography.hazmat.primitives import padding def pad_data(data, block_size=128): # 创建填充器 padder = padding.PKCS7(block_size).padder() padded_data = padder.update(data) + padder.finalize() return padded_data def unpad_data(padded_data, block_size=128): # 创建解填充器 unpadder = padding.PKCS7(block_size).unpadder() unpadded_data = unpadder.update(padded_data) + unpadder.finalize() return unpadded_data # 测试 original_data = b"Hello, World!" print("原始数据:", original_data) # 填充 padded_data = pad_data(original_data) print("填充后数据:", padded_data) # 解填充 unpadded_data = unpad_data(padded_data) print("解填充后数据:", unpadded_data) ``` ### 注意事项 1. 块大小必须是位(bit)单位,且是8的倍数(因为一个字节8位)。例如,AES的块大小是128位(16字节)。 2. 填充操作要求输入数据是字节(bytes)类型。 3. 解填充,如果填充不正确,`finalize()`方法会抛出`ValueError`异常。 ### 其他填充方式 cryptography库还提供了其他填充方式,例如: - `ANSIX923`:与PKCS7类似,但填充字节除了最后一个字节表示填充长度外,其他都是0。 - `PKCS7`:最常用,每个填充字节的值等于填充的字节数。 - `ISO10126`:已被弃用。 使用方式与PKCS7类似,只需在创建填充器替换为相应的类即可。 ### 引用说明 在对称加密中,填充是重要的步骤,用于确保数据长度符合加密算法的块大小要求[^2]。 §§相关问题§§ 1. 在什么情况下需要自定义填充方案? 2. 如何选择适合的填充方式? 3. 填充过程中可能遇到哪些安全问题?</think>### cryptography 库中的 Padding 方法详解 在密码学中,**填充(Padding)** 是确保明文长度符合加密算法块大小要求的关键步骤。`cryptography` 库通过 `hazmat.primitives.padding` 模块提供多种填充方案实现,以下是核心方法详解: --- #### 1. **支持的填充类型** `cryptography` 提供三种主流填充方案: - **PKCS7**:最常用的填充标准(兼容 PKCS#5) - **ANSIX923**:填充字节为 `0x00`,末字节为填充长度 - **ISO7816**:首个填充字节为 `0x80`,其余为 `0x00` ```python from cryptography.hazmat.primitives import padding # 初始化填充器示例 padder_pkcs7 = padding.PKCS7(block_size=128).padder() # AES 块大小=128位 padder_ansix923 = padding.ANSIX923(block_size=128).padder() ``` --- #### 2. **填充操作步骤** **步骤 1:创建填充器** ```python from cryptography.hazmat.primitives.padding import PKCS7 padder = PKCS7(block_size=128).padder() # 块大小单位:位(bit) ``` **步骤 2:应用填充** ```python data = b"Secret data" # 原始字节数据 padded_data = padder.update(data) + padder.finalize() # 输出:b'Secret data\x05\x05\x05\x05\x05' (PKCS7 填充结果) ``` **步骤 3:解密后移除填充** ```python unpadder = PKCS7(block_size=128).unpadder() unpadded_data = unpadder.update(padded_data) + unpadder.finalize() # 输出:b"Secret data" ``` --- #### 3. **填充原理对比** | 填充类型 | 填充规则 | 示例(需填充 5 字节) | |----------------|--------------------------------------------------------------------------|-----------------------------| | **PKCS7** | 每个填充字节的值等于填充长度 | `... \x05\x05\x05\x05\x05` | | **ANSIX923** | 填充 `0x00`,末字节为填充长度 | `... \x00\x00\x00\x00\x05` | | **ISO7816** | 首字节 `0x80`,后续为 `0x00` | `... \x80\x00\x00\x00\x00` | | **零填充** | 填充 `0x00`(需手动实现,cryptography 未内置) | `... \x00\x00\x00\x00\x00` | > **注意**:块大小必须为 **8 的倍数**(如 AES=128/256位),单位是**位(bit)** 而非字节[^2]。 --- #### 4. **完整加密-解密流程示例** ```python from cryptography.hazmat.primitives import padding, hashes from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend import os # 生成随机密钥和 IV key = os.urandom(32) # AES-256 iv = os.urandom(16) # 加密流程 cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) encryptor = cipher.encryptor() padder = padding.PKCS7(128).padder() plaintext = b"Data to encrypt" padded_data = padder.update(plaintext) + padder.finalize() ciphertext = encryptor.update(padded_data) + encryptor.finalize() # 解密流程 decryptor = cipher.decryptor() unpadder = padding.PKCS7(128).unpadder() decrypted_padded = decryptor.update(ciphertext) + decryptor.finalize() decrypted_data = unpadder.update(decrypted_padded) + unpadder.finalize() # decrypted_data == b"Data to encrypt" ``` --- #### 5. **重要注意事项** 1. **块大小匹配**:填充块大小需与加密算法块大小一致(如 AES=128位) 2. **安全风险**: - 使用 CBC 模式需结合 HMAC 防止填充预言攻击(Padding Oracle) - 推荐用 AEAD 模式(如 AES-GCM)替代手动填充[^1] 3. **错误处理**: ```python try: unpadded_data = unpadder.update(data) + unpadder.finalize() except ValueError: print("无效填充!可能遭篡改") ``` --- ### 常见问题解答 **Q:为什么解密出现 `ValueError: Invalid padding bytes`?** A:通常由两种原因导致: 1. 密钥/IV 错误导致解密后填充字节无效 2. 数据在传输中被篡改 **Q:如何选择填充方案?** - 通用场景:优先用 **PKCS7**(行业标准) - 特定协议:遵循协议规范(如 ANSIX923 用于金融系统) **Q:零填充(Zero Padding)为何不安全?** 零填充无法区分真实数据末尾的 `0x00` 和填充字符,可能导致数据截断错误[^2]。 --- ### 总结 `cryptography` 库通过标准化接口实现了 PKCS7、ANSIX923 和 ISO7816 填充方案,核心步骤包括: 1. 初始化填充器/解填充器 2. 使用 `update()` 处理数据 3. 调用 `finalize()` 完成操作 正确使用填充机制是保障对称加密(如 AES-CBC)安全性的基础环节[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值