1 加密模式
ECB : Electronic codebook, 电子密码本. 需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密
- 优点 : 可以并行处理数据
- 缺点 : 同样的原文生成同样的密文, 不能很好的保护数据
- 同时加密,原文是一样的,加密出来的密文也是一样的
CBC : Cipher-block chaining, 密码块链接. 每个明文块先与前一个密文块进行异或后,再进行加密。在这种方法中,每个密文块都依赖于它前面的所有明文块
- 优点 : 同样的原文生成的密文不一样
- 缺点 : 串行处理数据.
2 填充模式
当需要按块处理的数据, 数据长度不符合块处理需求时, 按照一定的方法填充满块长的规则
NoPadding
- 不填充.
- 在DES加密算法下, 要求原文长度必须是8byte的整数倍
- 在AES加密算法下, 要求原文长度必须是16byte的整数倍
PKCS5Padding
数据块的大小为8位, 不够就补足
3 常用的加密填充模式
AES/CBC/NoPadding (128)
AES/CBC/PKCS5Padding (128)
AES/ECB/NoPadding (128)
AES/ECB/PKCS5Padding (128)
DES/CBC/NoPadding (56)
DES/CBC/PKCS5Padding (56)
DES/ECB/NoPadding (56)
DES/ECB/PKCS5Padding (56)
DESede/CBC/NoPadding (168)
DESede/CBC/PKCS5Padding (168)
DESede/ECB/NoPadding (168)
DESede/ECB/PKCS5Padding (168)
RSA/ECB/PKCS1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
- 默认情况下, 加密模式和填充模式为 : ECB/PKCS5Padding
- 如果使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new IvParameterSpec(key.getBytes());
4 代码示例
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.junit.Before;
import org.junit.Test;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* @author huwenlong
* @date 2020/9/18 20:22
*/
public class Des {
private Cipher cipher;
private SecretKeySpec secretKeySpec;
private IvParameterSpec ivParameterSpec;
@Before
public void init() throws Exception {
String type = "AES";
String pattern = "AES/CBC/PKCS5Padding";
cipher = Cipher.getInstance(pattern);
// AES加密key是16位字符串
String key = "hello12345678911";
secretKeySpec = new SecretKeySpec(key.getBytes(), type);
ivParameterSpec = new IvParameterSpec(key.getBytes());
}
@Test
public void testEncipher() throws Exception {
System.out.println(encipher("hello")); // jtElayKS51OV98k4g2FX9A==
}
@Test
public void testDecipher() throws Exception {
System.out.println(decipher(encipher("hello"))); // hello
}
public String encipher(String str) throws Exception {
// 设置加密规则,如果加密模式是CBC加密则需要设置ivParameterSpec
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
return Base64.encode(cipher.doFinal(str.getBytes()));
}
public String decipher(String str) throws Exception {
// 设置解密规则,如果加密模式是CBC加密则需要设置ivParameterSpec
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
return new String(cipher.doFinal(Base64.decode(str)));
}
}