Java中PBEWithHmacSHA256AndAES_128加密算法内部运行机制问询
核心结论
PBEWithHmacSHA256AndAES_128的内部逻辑和你猜测的SSL类“明文+HMAC摘要后加密”、“密文后附加HMAC”的模式完全不同,名称中的HmacSHA256仅作用于密钥派生阶段,不参与明文/密文的完整性校验,这就是你加密单个字符仅得到16字节输出的核心原因。
1 算法完整运行流程
该算法属于PKCS#5 v2.1定义的PBES2方案,全流程分为两步:
- 第一步:密钥派生。以输入的密码、盐、迭代次数为参数,将
HmacSHA256作为伪随机函数执行PBKDF2派生,得到刚好128位(16字节)的AES加密密钥。此环节的HMAC运算仅和密码、盐、迭代次数相关,完全不接触明文/密文内容。 - 第二步:对称加密。用派生得到的AES密钥,按默认的
AES/CBC/PKCS5Padding模式对明文做加密。整个加密过程不会附加任何摘要信息,你加密单个字符时,明文加PKCS5填充刚好凑满1个16字节的AES块,最终输出就是16字节,和你观察到的现象完全吻合。
2 常见疑问解答
- 为什么和常规HMAC用法不一致?
该算法名称中的HmacSHA256仅用于标记密钥派生环节使用的哈希算法,本身默认不提供完整性校验能力。解密时只要参数符合格式,不管密码是否正确都会尝试解密,仅在填充校验失败时抛出BadPaddingException,这种校验强度极低,很容易被攻击绕过。 - 如何实现不存储原始密码、仅靠HMAC校验密码有效性的需求?
你当前的实现方案是可行的:单独调用PBKDF2WithHmacSHA1/PBKDF2WithHmacSHA256,使用和加密密钥派生完全独立的盐值、迭代次数生成校验专用密钥,计算明文或密文的HMAC值后附加在密文末尾存储即可。注意不要复用加密密钥做HMAC运算,避免产生安全风险。
如果不想自己处理HMAC拼接,也可以直接换用带认证加密的PBE算法,比如PBEWithHmacSHA256AndAES_128/GCM/NoPadding,GCM模式本身会在加密过程中生成认证标签,同时实现机密性和完整性校验,无需额外开发。
内容的提问来源于stack exchange,提问作者Bashi
相关产品推荐
相关产品推荐

