1. CBC(Cipher Block Chaining,密码分组链接模式)
概述
CBC 模式是一种常见的块密码工作模式,通过将每个明文块与前一个密文块进行异或操作,再进行加密,从而增强数据的安全性。
工作原理
-
初始向量(IV,Initialization Vector):
- CBC 模式需要一个随机生成的 IV 来确保相同明文在不同加密过程中的密文不同。
-
加密过程:
- 步骤 1:将第一个明文块与 IV 进行异或(XOR)操作。
- 步骤 2:将异或后的结果通过块密码算法(如 AES)加密,生成第一个密文块。
- 步骤 3:将第一个密文块与第二个明文块进行异或,再加密生成第二个密文块。
- 步骤 4:重复上述步骤,直到所有明文块都被加密。
-
解密过程:
- 步骤 1:将第一个密文块解密,得到异或后的数据。
- 步骤 2:将解密后的数据与 IV 进行异或,恢复出第一个明文块。
- 步骤 3:将解密后的密文块与下一个密文块进行异或,恢复出下一个明文块。
- 步骤 4:重复上述步骤,直到所有密文块都被解密。
特点
- 依赖性:每个密文块都依赖于前一个密文块,增强了安全性。
- 随机性:使用 IV 增加了加密的随机性,防止相同明文生成相同密文。
- 错误传播:在解密过程中,如果某个密文块损坏,将导致该块和下一个块的解密失败。
优点
- 增强安全性:通过链接操作,使得相同的明文块在不同的加密过程中生成不同的密文块。
- 简单易实现:实现相对简单,广泛支持于各种加密库和标准中。
缺点
- 无法并行处理:由于每个密文块依赖于前一个密文块,加密和解密过程无法并行化,影响性能。
- 错误传播:解密过程中,某个密文块的错误会影响到当前块和下一个块的解密结果。
适用场景
- 文件加密:如加密文件系统中的数据。
- 通信加密:如 SSL/TLS 的部分加密阶段。
- 通用数据保护:适用于需要高度安全性的场合。
2. CFB(Cipher Feedback,密码反馈模式)
概述
CFB 模式将块密码转换为一种类似流密码的工作模式,可以处理任意长度的数据流。它通过将前一个密文块反馈到加密过程中,实现对明文的加密。
工作原理
-
初始向量(IV):
- CFB 模式同样需要一个随机生成的 IV 来确保加密的随机性。
-
加密过程:
- 步骤 1:将 IV 加密,得到一个密钥流块。
- 步骤 2:将密钥流块与第一个明文块进行异或,生成第一个密文块。
- 步骤 3:将第一个密文块作为下一个加密过程的输入,加密后得到下一个密钥流块。
- 步骤 4:将第二个密钥流块与第二个明文块进行异或,生成第二个密文块。
- 步骤 5:重复上述步骤,直到所有明文块被加密。
-
解密过程:
- 步骤 1:将 IV 加密,得到密钥流块。
- 步骤 2:将密钥流块与第一个密文块进行异或,恢复出第一个明文块。
- 步骤 3:将第一个密文块作为下一个加密过程的输入,加密后得到下一个密钥流块。
- 步骤 4:将第二个密钥流块与第二个密文块进行异或,恢复出第二个明文块。
- 步骤 5:重复上述步骤,直到所有密文块被解密。
特点
- 反馈机制:密文块反馈到加密过程,增强了安全性。
- 类似流密码:能够处理任意长度的数据,与流密码类似。
优点
- 灵活性高:可以处理任意长度的数据,而不仅限于块大小的整数倍。
- 无需填充:不需要像 CBC 模式那样进行填充操作,简化了实现。
- 错误局部化:单个密文块的错误只会影响对应的明文块,错误不会传播到其他块。
缺点
- 无法并行处理:与 CBC 模式类似,加密和解密过程需要串行进行,影响性能。
- 安全性依赖于反馈:需要确保反馈机制的安全性,否则可能导致攻击风险。
适用场景
- 流式通信:如实时数据传输、网络通信加密。
- 无线通信:适用于需要快速响应和低延迟的场合。
- 即时消息传输:如聊天应用中的数据加密。
3. OFB(Output Feedback,输出反馈模式)
概述
OFB 模式也是将块密码转换为一种流密码的模式,通过不断生成密钥流来与明文进行异或,从而实现加密。与 CFB 不同的是,OFB 模式使用块密码的输出作为密钥流的生成源,而不依赖于密文。
工作原理
-
初始向量(IV):
- 与 CBC 和 CFB 模式类似,OFB 也需要一个随机的 IV。
-
密钥流生成:
- 步骤 1:将 IV 输入块密码算法,得到第一个密钥流块。
- 步骤 2:将第一个密钥流块再次输入块密码算法,生成第二个密钥流块。
- 步骤 3:重复上述步骤,持续生成密钥流块,直到覆盖所有明文数据。
-
加密过程:
- 步骤 1:将生成的密钥流块与明文数据进行异或(XOR)操作,生成密文块。
- 步骤 2:重复以上步骤,直到所有数据块都被加密。
-
解密过程:
- 由于 XOR 操作的对称性,解密过程与加密过程相同,将密钥流块与密文块进行异或,恢复出明文。
特点
- 独立性:密钥流的生成独立于明文和密文,只依赖于初始向量和密钥。
- 同步流密码:可以预先生成密钥流,适用于需要同步流密码的场合。
优点
- 并行性高:密钥流可以提前生成或并行处理,提高加密和解密性能。
- 无错误传播:单个密文块的错误只会影响对应的明文块,错误不会传播到其他块。
- 无需填充:无需像 CBC 模式那样进行填充操作,简化了实现。
缺点
- 无内建认证:OFB 模式仅提供加密功能,不提供数据完整性和认证保障,容易受到重放攻击等威胁。
- IV 重复风险:如果 IV 被重复使用,可能导致密钥流重复,破坏安全性。因此,必须确保 IV 的唯一性。
适用场景
- 广播通信:如加密广播数据流。
- 实时系统:需要快速生成密钥流并进行加密的场合。
- 高性能应用:如视频流、音频流加密。
CBC、CFB 和 OFB 模式的比较
特性 | CBC | CFB | OFB |
---|---|---|---|
加密类型 | 块加密模式 | 混合块加密和流加密 | 流加密模式 |
初始向量(IV) | 需要 | 需要 | 需要 |
并行处理 | 不支持加密,支持解密的部分并行 | 不支持并行 | 支持加密和解密的并行 |
错误传播 | 解密时错误会影响当前和下一个块 | 错误只影响对应的块 | 错误只影响对应的块 |
适用场景 | 文件加密、通信加密 | 流式传输、实时通信 | 高性能流加密、广播通信 |
安全性 | 高,但依赖于 IV 的唯一性和安全性 | 高,但依赖于 IV 的唯一性和安全性 | 高,但需要防止 IV 重复使用 |
需要填充 | 需要 | 不需要 | 不需要 |
总结
-
CBC 模式:适用于需要高度安全性但对性能要求不高的场景,如文件加密和常规通信加密。其串行依赖性限制了并行处理能力,且错误传播可能影响到多个密文块。
-
CFB 模式:适用于流式数据加密,如实时通信和无线通信。虽然提供了类似流密码的灵活性,但同样存在无法并行处理的限制。
-
OFB 模式:适用于需要高性能和并行处理的场景,如视频流和音频流加密。其密钥流的独立性使得加密和解密过程可以并行进行,但缺乏内建的认证机制,需要额外的手段来保证数据完整性。
在实际应用中,选择哪种加密模式取决于具体的需求,包括数据类型、性能要求、安全性需求以及系统的特性。对于需要同时保证数据机密性和完整性的场景,可能需要结合使用认证机制(如 HMAC)或选择带认证功能的加密模式(如 GCM)。
示例代码(Java)
以下是使用 Java 实现 CBC、CFB 和 OFB 模式的示例代码
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
/**
*
* 支持 CBC CFB OFB
*/
public class AES {
private static Logger log = LoggerFactory.getLogger(AES.class);
//默认模式
private static String DEFAULT_MODE = "AES/CBC/PKCS5Padding";
//默认key
private static final String DEFAULT_KEY = "hqsywqVnGKaEYka1";
//默认初始向量
private static final String DEFAULT_IV = "TlP5B1wg7zMnmQHT";
public static Build build(String key, String mode) {
return new Build(key, mode);
}
public static Build build() {
return new Build();
}
public static class Build {
private Cipher cipher;
private String key = DEFAULT_KEY;
private String mode = DEFAULT_MODE;
private String result;
private String iv = DEFAULT_IV;
private String padding;
public Build() {
}
public Build(String key, String mode) {
if (StringUtils.isNotBlank(key)) {
this.key = key;
}
if (StringUtils.isNotBlank(mode)) {
this.mode = mode;
}
}
/**
* 初始化
* @return
*/
public Build init() {
try {
cipher = Cipher.getInstance(mode);
} catch (Exception e) {
log.error("初始化aes失败:", e);
}
return this;
}
/**
* 加密
* @param enc
* @return
*/
public Build encrypt(String enc) {
if (cipher == null) {
init();
}
try {
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key), getIvParameterSpec(iv));
byte[] bytes = cipher.doFinal(enc.getBytes(StandardCharsets.UTF_8));
result = Base64.getEncoder().encodeToString(bytes);
} catch (Exception e) {
log.error("aes加密失败:", e);
}
return this;
}
/**
* 解密
* @param dec
* @return
*/
public Build decrypt(String dec) {
if (cipher == null) {
init();
}
try {
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key), getIvParameterSpec(iv));
byte[] bytes = cipher.doFinal(Base64.getDecoder().decode(dec));
result = new String(bytes);
} catch (Exception e) {
log.error("aes解密失败:", e);
}
return this;
}
public String build() {
return result;
}
}
// 将字符串转换为初始化向量
public static IvParameterSpec getIvParameterSpec(String ivStr) {
return new IvParameterSpec(ivStr.getBytes(StandardCharsets.UTF_8));
}
/**
* 生成密钥
* @param key
* @return
*/
public static SecretKey getSecretKey(String key) {
byte[] bytes = key.getBytes(StandardCharsets.UTF_8);
return new SecretKeySpec(bytes, 0, key.length(), "AES");
}
public static void main(String[] args) {
//支持 CBC CFB OFB
Build init = AES.build("1232QWE131ASD2Q2","AES/CBC/PKCS5Padding").init();
String enc = init.encrypt("123").build();
System.out.println(enc);
String dec = init.decrypt(enc).build();
System.out.println(dec);
}
}
注意事项
-
密钥管理:
- 密钥必须安全地存储和管理,避免泄露。可以使用 Java 的
KeyStore
来管理密钥。 - 不建议在代码中硬编码密钥。
- 密钥必须安全地存储和管理,避免泄露。可以使用 Java 的
-
初始化向量(IV):
- 每次加密操作应使用不同且随机生成的 IV,以确保密文的唯一性。
- IV 本身不需要保密,但必须与密文一起存储或传输,以便解密时使用。
-
填充方式:
- 在 CBC 模式下,需要填充(如 PKCS5Padding)以确保明文长度是块大小的整数倍。
-
安全性:
- 确保使用最新的 Java 版本和安全库,以防止已知的安全漏洞。
- 考虑结合使用认证机制(如 HMAC)以增强数据完整性和防御主动攻击。
-
异常处理:
- 加密和解密过程中可能会抛出各种异常,应妥善处理,确保系统的稳定性和安全性。