Python加密数据时的非ASCII字符转换处理

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)

关键点总结

  1. 所有文本在加密前必须先编码为bytes (encode('utf-8'))
  2. 加密后的二进制数据可以转换为Base64字符串方便显示/传输
  3. PEM格式的密钥已经是ASCII安全格式
  4. 解密后记得将bytes解码回字符串 (decode('utf-8'))

这样处理可以避免"bytes can only contain ASCII literal characters"错误,同时保证中文等非ASCII字符的正确处理。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值