密码学是隐藏或混淆数据的过程,Shiro 简化了 JDK 的加密并使其变得易用。
Shiro 提供的加密支持可在任何地方使用,并非特定于 Subject
。
Shiro 真正关注的加密支持包括:Hashing(也称消息摘要,message digests)和 Ciphers。
Hashing
以 MD5 散列文件为例,通常提供文件下载功能的地方会同时提供一个校验码(checksum),用户可以在已下载的文件上执行 MD5 哈希,并将结果与校验码(checksum)进行匹配以判断下载文件的完整性。
使用 JDK 原生 MessageDigest
API:
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.digest(bytes);
byte[] hashed = md.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
对比使用 Shiro:
String hex = new Md5Hash(myFile).toHex();
Shiro 加密代码明显更加简单和易懂。
SHA-512哈希和密码的Base64编码同样简单:
String encodedPassword = new Sha512Hash(password, salt, count).toBase64();
Ciphers
Ciphers 是一类使用密钥逆向转换数据的加密算法,用于保护数据安全,尤其是传输和存储数据的安全。
Shiro CipherService
API 简化了 Ciphers
的整体概念。CipherService
是一个简单、无状态且线程安全的 API,可以在一个方法调用中完整地加密或解密数据。示例:
AesCipherService cipherService = new AesCipherService();
cipherService.setKeySize(256);
// 生成密钥
byte[] testKey = cipherService.generateNewKey();
// 执行加密
byte[] encrypted = cipherService.encrypt(fileBytes, testKey);
与 JDK Cipher
API 相比 Shiro 要简单得多:
- 可以直接初始化
CipherService
实例,不像 JDKCipher
API 那样调用工厂方法; - 配置选项兼容 JavaBeans Getter 和 Setter,没有奇怪且难以理解的转换字符串;
- 使用一个方法调用便能实现加密和解密;
- 没有强制检查异常,如果需要可以捕获 Shiro
CryptoException
。
Shiro’s CipherService
API 还有一些其它优势,包括支持基于字节数组(byte array)和流(stream)的加解密,譬如音视频加密。