Python加密数据时的非ASCII字符转换处理,即解决 "bytes can only contain ASCII literal characters" 错误
这个错误通常发生在尝试将非ASCII字符直接转换为字节字符串(bytes)时。在Python中处理加密数据时经常遇到这个问题。以下是解决方案和最佳实践:
问题原因
当您尝试类似这样的操作时会报错:
b"非ASCII字符" # 错误:bytes can only contain ASCII literal characters
解决方案
1. 对字符串进行编码
text = "这是一些中文文本"
byte_data = text.encode('utf-8') # 正确转换为bytes
2. 在加密/解密场景中的正确处理
以RSA加密为例的正确方式:
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
# 要加密的文本
message = "这是一条秘密消息"
# 正确转换为bytes
message_bytes = message.encode('utf-8')
# 加密
ciphertext = public_key.encrypt(
message_bytes,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# 解密后转换回字符串
decrypted_bytes = private_key.decrypt(
ciphertext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
decrypted_text = decrypted_bytes.decode('utf-8')
3. 处理Base64编码数据
如果需要打印或传输加密数据,建议使用Base64编码:
import base64
# 加密数据转换为Base64字符串
encrypted_b64 = base64.b64encode(ciphertext).decode('ascii')
print("加密数据(Base64):", encrypted_b64)
# 从Base64解码
decoded_ciphertext = base64.b64decode(encrypted_b64)
4. 密钥序列化时的处理
当处理PEM格式的密钥时:
from cryptography.hazmat.primitives import serialization
# 私钥序列化
pem_private = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
# PEM格式本身就是ASCII,可以直接解码为字符串
pem_private_str = pem_private.decode('ascii')
完整示例
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
import base64
# 生成密钥对
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048
)
public_key = private_key.public_key()
# 要加密的消息
message = "这是一条包含中文的秘密消息"
# 正确转换为bytes
message_bytes = message.encode('utf-8')
# 加密
ciphertext = public_key.encrypt(
message_bytes,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# 转换为Base64方便显示/传输
encrypted_b64 = base64.b64encode(ciphertext).decode('ascii')
print("加密数据(Base64):", encrypted_b64)
# 解密
decrypted_bytes = private_key.decrypt(
base64.b64decode(encrypted_b64),
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
decrypted_text = decrypted_bytes.decode('utf-8')
print("解密后的消息:", decrypted_text)
关键点总结
- 所有文本在加密前必须先编码为bytes (
encode('utf-8')) - 加密后的二进制数据可以转换为Base64字符串方便显示/传输
- PEM格式的密钥已经是ASCII安全格式
- 解密后记得将bytes解码回字符串 (
decode('utf-8'))
这样处理可以避免"bytes can only contain ASCII literal characters"错误,同时保证中文等非ASCII字符的正确处理。
1731

被折叠的 条评论
为什么被折叠?



