加解密过程中为何需要将十六进制值转换为字节类型
为什么加解密流程通常要把十六进制格式值转为字节类型
核心原因是密码学算法的运算逻辑天生基于二进制字节设计,十六进制只是二进制数据面向人类可读、跨环境传输的一种文本表示形式,不是算法可直接处理的输入格式,具体可以拆成三点:
- 算法底层运算的要求:AES这类对称加密算法是按固定长度的二进制块做移位、异或、替换等运算的,比如AES块大小固定为128位也就是16字节,所有运算的输入输出都是原生字节序列。十六进制字符串本质是普通文本,每2个字符才对应1个实际字节,直接传入的话算法无法按块切分、执行底层运算。
- 消除数据歧义:如果直接用文本类输入,不同编码规则(UTF-8、GBK等)会把相同的文本映射成完全不同的字节序列,会导致加解密结果不可控。转成字节类型相当于把输入固定为无歧义的二进制形态,保证加解密逻辑在不同环境下的运行结果一致。
- 适配传输链路的需求:加解密产生的密文、IV、密钥这类数据里包含大量不可见控制字符,直接在网络请求、Cookie、日志里传输原始字节很容易出现字符转义、截断、编码损坏的问题,所以业务里通常会把这类二进制数据编码成十六进制(或Base64)的纯文本格式传输,到实际执行加解密的环节,就必须先把这类传输用的文本还原回原始字节。
对应给出的AES-CBC权限校验代码,做十六进制转字节的原因非常明确:
- 适配接口入参的形态:这个校验函数的
cookie和iv入参都是从外部请求拿到的,不管是从URL参数、Cookie还是请求体里取到的值,默认都是字符串类型,存的是密文、IV的十六进制文本,不是解密逻辑需要的二进制数据。 - 满足密码库的参数要求:代码里调用的
AES.new()初始化方法对参数类型有强校验:CBC模式要求传入的IV必须是长度16字节的字节类型,decrypt()方法要求待解密的密文也必须是字节类型、且长度为16字节的整数倍,直接传入十六进制字符串会直接触发类型错误,根本无法完成密码实例初始化和解密操作。 - 保证后续逻辑正常运行:只有把十六进制格式的cookie、IV还原成原始字节,后续的解密、PKCS7去填充操作才能输出正确的明文,后续判断明文里是否包含
admin=True的权限校验逻辑才有意义。
def check_admin(cookie, iv): cookie = bytes.fromhex(cookie) iv = bytes.fromhex(iv) try: cipher = AES.new(KEY, AES.MODE_CBC, iv) decrypted = cipher.decrypt(cookie) unpadded = unpad(decrypted, 16) except ValueError as e: return {"error": str(e)} if b"admin=True" in unpadded.split(b";"): return {"flag": FLAG} else: return {"error": "Only admin can read the flag"}
内容的提问来源于stack exchange,提问作者Shubham Jagtap
相关产品推荐
相关产品推荐

