一、简介
Java Cryptography Extension(JCE)是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。它提供对对称、不对称、块和流密码的加密支持,它还支持安全流和密封的对象。它不对外出口,用它开发完成封装后将无法调用。
在早期JDK版本中,由于受美国的密码出口条例约束,Java中涉及加解密功能的API被限制出口,所以Java中安全组件被分成了两部分: 不含加密功能的JCA(Java Cryptography Architecture )和含加密功能的JCE(Java Cryptography Extension)。
在JDK1.1-1.3版本期间,JCE属于扩展包,仅供美国和加拿大的用户下载,JDK1.4+版本后,随JDK核心包一起分发。
二、加解密
JCE的API都在 javax.crypto 包下,核心功能包括:加解密、密钥生成(对称)、MAC生成、密钥协商。
1. Cipher
加解密功能由Cipher组件提供,其也是JCE中最核心的组件。
Cipher的几个知识点:
- Cipher在使用时需以参数方式指定transformation
- transformation的格式为algorithm/mode/padding(算法/模式/填充),其中algorithm(算法)为必输项,如: DES/CBC/PKCS5Padding
- 缺省的mode为ECB,缺省的padding为PKCS5Padding
- 在block算法与流加密模式组合时, 需在mode后面指定每次处理的bit数, 如DES/CFB8/NoPadding, 如未指定则使用缺省值, SunJCE缺省值为64bits
- Cipher有4种操作模式: ENCRYPT_MODE(加密), DECRYPT_MODE(解密), WRAP_MODE(导出Key), UNWRAP_MODE(导入Key),初始化时需指定某种操作模式(都是静态参数)。
2. 对称加密的算法与密钥长度选择
算法名称 | 密钥长 | 块长 | 速度 | 说明 |
---|---|---|---|---|
DES | 56 | 64 | 慢 | 不安全, 不要使用 |
3DES | 112/168 | 64 | 很慢 | 中等安全, 适合加密较小的数据 |
AES | 128, 192, 256 | 128 | 快 | 安全 |
Blowfish | (4至56)*8 | 64 | 快 | 应该安全, 在安全界尚未被充分分析、论证 |
RC4 | 40-1024 | 64 | 很快 | 安全性不明确 |
一般情况下,不要选择DES算法,推荐使用AES算法。一般认为128bits的密钥已足够安全,如果可以请选择256bits的密钥。
<1>密钥长度是在生成密钥时指定的。如:
KeyGenerator generator = KeyGenerator.getInstance("AES/CBC/PKCS5PADDING");
generator.init(256);
SecretKey key = generator.generateKey();
<2>生成长度超128bits的密钥,需单独从Oracle官网下载对应JDK版本的Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files文件《详见: java加密——Jasypt开源工具包》,例如JDK7对应的jurisdiction policy files。
3.加密示例代码
/**
* 根据密钥{@link #getKey()}对指定的明文
plainText
进行加密.
*
* @param plainText 明文
* @return 加密后的密文.
*/
public static final String encrypt(String plainText) {
Key secretKey = getKey();
try {
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] p = plainText.getBytes("UTF-8");
byte[] result = cipher.doFinal(p);
BASE64Encoder encoder = new BASE64Encoder();
String encoded = encoder.encode(result);
return encoded;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
4.解密示例代码
/**
* 根据密钥{@link #getKey()}对指定的密文
cipherText
进行解密.
*
* @param cipherText 密文
* @re