Python实现简易OTP遇AES密钥长度错误,求技术解答
嘿,我来帮你搞定这个问题~
首先,咱们先搞清楚你遇到的AES密钥长度错误是怎么回事,然后再聊聊你提到的OTP(一次性密码本)的正确实现方式,因为看起来你可能把AES和OTP的概念混淆啦。
一、解决AES密钥长度错误
错误原因
AES加密算法对密钥长度有严格的硬性要求,它只认三种长度的密钥:
- 16字节(对应AES-128)
- 24字节(对应AES-192)
- 32字节(对应AES-256)
你的密钥secret_key = '1234567890'只有10个字符(也就是10字节),完全不符合AES的要求,所以才会抛出ValueError: Incorrect AES key length的错误。另外,AES还有个要求:加密的明文长度必须是16字节(AES的块大小)的整数倍,所以咱们还得给输入的文本做个“填充”处理,不然也会报错。
修正后的AES代码
我给你调整了代码,不仅修复了密钥长度问题,还加了填充处理,你可以直接运行试试:
from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad import base64 # 获取用户输入并转成字节串(AES操作的是字节,不是字符串) user_input = input("Write here: ").encode('utf-8') # 把密钥改成16字节的(符合AES-128要求),你可以换成自己的密钥,但必须是16/24/32字节 secret_key = b'1234567890abcdef' # 用字节串更稳妥,避免编码问题 # 初始化AES加密器(注意:ECB模式安全性很低,实际项目里建议用CBC或GCM模式) cipher = AES.new(secret_key, AES.MODE_ECB) # 加密流程:填充明文 → 加密 → base64编码(方便展示和传输) padded_text = pad(user_input, AES.block_size) encrypted_bytes = cipher.encrypt(padded_text) encoded_result = base64.b64encode(encrypted_bytes).decode('utf-8') print(f"加密结果: {encoded_result}") # 解密流程:base64解码 → 解密 → 去掉填充 decrypted_bytes = cipher.decrypt(base64.b64decode(encoded_result)) decoded_result = unpad(decrypted_bytes, AES.block_size).decode('utf-8') print(f"解密结果: {decoded_result}")
二、如果你真的想实现OTP(一次性密码本)
你提到要做OTP,但AES可不是OTP哦!OTP是一种理论上绝对安全的加密方式,核心要求有三个:
- 密钥长度必须和明文长度完全一样
- 密钥必须是完全随机的字节串(不能是像'1234567890'这种可预测的字符串)
- 密钥只能用一次,用完就销毁,绝对不能重复使用
下面是一个简易的OTP实现代码,完全符合上述要求:
import os def otp_encrypt_decrypt(plaintext_or_ciphertext, key): # 先检查明文/密文和密钥长度是否一致 if len(plaintext_or_ciphertext) != len(key): raise ValueError("文本和密钥必须长度相同!") # OTP的核心就是异或操作:加密和解密用同一个函数,因为异或两次就会还原 result = bytes([byte ^ key_byte for byte, key_byte in zip(plaintext_or_ciphertext, key)]) return result # 示例使用 user_input = input("Write here: ").encode('utf-8') # 生成和明文长度相同的随机密钥(用os.urandom生成真随机字节,比伪随机安全) otp_key = os.urandom(len(user_input)) # 加密 encrypted_data = otp_encrypt_decrypt(user_input, otp_key) print(f"加密结果(十六进制格式): {encrypted_data.hex()}") print(f"请妥善保存这个OTP密钥(解密必须用它): {otp_key.hex()}") # 解密(必须用同一个密钥) decrypted_data = otp_encrypt_decrypt(encrypted_data, otp_key) print(f"解密结果: {decrypted_data.decode('utf-8')}")
关于OTP的重要提醒
- 密钥一定要和明文长度一致,不然没法加密/解密
- 密钥必须是真随机的,绝对不能用重复的密钥,也不能用有规律的字符串当密钥
- 密钥的传输和存储必须绝对安全,一旦密钥泄露或者被重复使用,OTP的“绝对安全”就彻底失效了
内容的提问来源于stack exchange,提问作者user9580162
相关产品推荐
相关产品推荐

