cryptography.fernet密钥异常:修改末尾字符仍可完成解密
问题原因分析:修改Fernet密钥末尾字符仍可解密的本质
你遇到的现象并非Fernet加密机制的漏洞,而是Base64编码的特性导致的——你修改的Base64字符并未真正改变底层的二进制密钥,因此解密流程完全正常。
核心原理拆解
Fernet密钥结构
Fernet密钥本质是32字节的二进制数据,通过URL-safe Base64编码后供用户使用。这32字节被分为两部分:- 前16字节:用于AES-128-CBC加密
- 后16字节:用于HMAC-SHA256签名验证(解密时必须验证签名通过才能解密)
Base64编码的位分配
URL-safe Base64将二进制数据按6位一组转换为字符。32字节共256位,计算可知:256 = 6×42 + 4
这意味着编码后的字符串有43个有效字符,最后添加1个=填充(凑齐4的倍数)。最后一个有效字符仅使用其6位中的前4位,剩余2位被忽略。
你修改的字符未改变二进制密钥
URL-safe Base64字符集中,0(编码值52,二进制110100)、1(53,110101)、2(54,110110)、3(55,110111)这四个字符的前4位完全相同(都是1101)。因此你修改最后一个字符在这四个值之间时,对应的二进制密钥的最后4位没有任何变化——底层的加密/签名密钥完全没变,解密自然能成功。
验证结论
你可以测试将密钥末尾改为4(编码值56,二进制111000,前4位为1110),比如使用密钥lIX2AfP-cyFRNgYgFRf3Sy3uKQ4Hrr4Lvrn12wFGo34=,此时底层二进制密钥的最后4位发生改变,HMAC签名验证会失败,解密流程会进入你代码中的except分支,提示重新输入密钥。
总结
Fernet的加密验证是严格的,只要真正修改了二进制密钥的任意有效位(非Base64编码中被忽略的位),就无法通过签名验证和解密。你之前的测试只是触碰了Base64编码的“冗余位”,并未改变实际密钥。
内容的提问来源于stack exchange,提问作者Stalfos1
相关产品推荐
相关产品推荐

