6. 基于口令的加密方案
有两个基于口令的加密PBES方案,如下表。
表5.1 基于口令的加密方案PBES1和PBES2对比
(hLen为HASH函数的输出长度)
项目 | PBES1 | PBES2 |
使用的PBKDF | PBKDF1 | PBKDF2 |
使用的密码算法 | DES / RC2 – CBC模式 | AES-CBC-Pad |
使用 | 不推荐 仅兼容PKCS5 v1.5 | 推荐使用 |
- AES-CBC-Pad是AES算法,密钥16/24/32字节,分组16字节,IV16字节。
- 根据PKCS#5的附录B.2.4 RC5-CBC-Pad 提到的RC5-128的填充方式,猜测AES-CBC-Pad的填充方式为:the padding string consists of 16-(||M||mod 16) octets each with value 16-(||M|| mod 16).
6.1 PBES1
PBES中对消息填充的方案(EM = M || PS)为:
- 记T = 8-(#M mod 8),
- 填充数据PS为连续T个字节且每个字节值均为T的字符串。
- 例:若#M mod 8 = 7,PS = 01
- 例:若#M mod 8 = 0,PS = 08 08 08 08 08 08 08 08
- 此填充规则来至于RFC 1423。
6.1.1 PBES1-ENC
函数:C = PBES1-ENC (M, P, S, c)
功能:基于口令的加密方案PBES1的加密算法
输入参数:
- M:明文。
- P:口令,任意长度的字符串(通常为ASCII 或UTF-8字符)。
- S:盐值,8字节。无需保密,增加密文多变性。
- c:迭代次数,越大越好,建议不小于1000。
内部参数:
- ENC-CBC:加密函数CBC模式(如AES-ENC-CBC)。
返回数据:
- C:密文。
执行步骤:
步骤1:生成导出密钥,DK = PBKDF1 (P, S, c, 16)。
步骤2:生成加密密钥K(DK的高8字节)和初始化向量IV(DK的低8字节):
K = DK[0...7], IV = DK[8...15] .
步骤3:生成编码后的消息(记T = 8-(#M mod 8))
EM = M || PS,
其中填充数据PS为连续T个字节且每个字节值均为T的字符串。
- 例:若#M mod 8 = 7,PS = 01
- 例:若#M mod 8 = 0,PS = 08 08 08 08 08 08 08 08
步骤4:CBC加密:C = ENC-CBC(K, IV, EM)。
步骤5:输出密文C。
6.1.2 PBES1-DEC
函数:M = PBES1-DEC (C, P, S, c)
功能:基于口令的加密方案PBES1的解密算法
输入参数:
- C:密文。
- P:口令,任意长度的字符串(通常为ASCII 或UTF-8字符)。
- S:盐值,8字节。无需保密,增加密文多变性。
- c:迭代次数,越大越好,建议不小于1000。
内部参数:
- DEC-CBC:解密函数CBC模式(如AES-DEC-CBC)。
返回数据:
- M:明文。
执行步骤:
步骤1:生成导出密钥,DK = PBKDF1 (P, S, c, 16)。
步骤2:生成加密密钥K(DK的高8字节)和初始化向量IV(DK的低8字节):
K = DK[0...7], IV = DK[8...15] .
步骤3:CBC解密:EM = DEC-CBC(K, IV, C)。
步骤4:解码生成编码后的消息
M || PS = EM。
记T 为EM最后一个字节的值,填充数据PS为连续T个字节且每个字节值均为T的字符串。如果PS不满足要求(1):T=1,2,...,8;(2)PS的T个字节的值都为T;则填充数据格式验证失败,返回错误。
步骤5:输出明文M。
6.2 PBES2
PBES中对消息填充的方案(EM = M || PS)为:
- 记T = 8-(#M mod 8),
- 填充数据PS为连续T个字节且每个字节值均为T的字符串。
- 例:若#M mod 8 = 7,PS = 01
- 例:若#M mod 8 = 0,PS = 08 08 08 08 08 08 08 08
- 此填充规则来至于RFC 1423。
6.2.1 PBES2-ENC
函数:C = PBES2-ENC (M, P, S, c)
功能:基于口令的加密方案PBES2的加密算法
输入参数:
- M:明文。
- P:口令,任意长度的字符串(通常为ASCII 或UTF-8字符)。
- S:盐值,8字节。无需保密,增加密文多变性。
- c:迭代次数,越大越好,建议不小于1000。
内部参数:
- dkLen:导出密钥DK的字节长度。
返回数据:
- C:密文。
执行步骤:(PKCS#5未详细描述dkLen、K和IV的获取,相关内容为揣测)
步骤1:根据选择的密码算法AES-CBC-Pad确定dkLen(自定义)。
步骤2:生成导出密钥,DK = PBKDF2 (P, S, c, dkLen)。
步骤3:加密:C = AES-CBC-Pad.ENC(DK, M)。(涉及K和IV的划分,自定义)
步骤4:输出密文C。
根据PKCS#5的附录B.2.4 RC5-CBC-Pad 提到的RC5-128的填充方式,猜测AES-CBC-Pad的填充方式为:the padding string consists of 16-(||M||mod 16) octets each with value 16-(||M|| mod 16).
6.2.2 PBES2-DEC
函数:M = PBES2-DEC (C, P, S, c)
功能:基于口令的加密方案PBES2的解密算法
输入参数:
- C:密文。
- P:口令,任意长度的字符串(通常为ASCII 或UTF-8字符)。
- S:盐值,8字节。无需保密,增加密文多变性。
- c:迭代次数,越大越好,建议不小于1000。
内部参数:
- dkLen:导出密钥DK的字节长度。
返回数据:
- M:明文。
执行步骤:(PKCS#5未详细描述dkLen、K和IV的获取,相关内容为揣测)
步骤1:根据选择的密码算法AES-CBC-Pad确定dkLen(自定义)。
步骤2:生成导出密钥,DK = PBKDF2 (P, S, c, dkLen)。
步骤3:解密:M = AES-CBC-Pad.DEC(DK, C)。(涉及K和IV的划分,自定义)
步骤4:输出明文M。