Apache Commons Crypto加密
admin 发布于:2022-06-19 21:58:11
阅读:loading
日常工作中会使用到的加密解密也是各种各样的,以本人来说文本编码(Base64);Apache Codec项目提供的MD5、SHA;基于公钥私钥的RSA非对称加密;JDK的对称加密;本篇文章主要是讲述对称加密的实现,简单理解对称加密是在加密文本时提供一个密钥的形式对文本加密,解密时需要提供此密钥,对于未知密钥的情况无法对文本进行解密,实际上JDK提供的对称加密写法在实现上还是略显复杂的,以至于个人一直处于排斥的心态,在看Apache Commons开源项目时,其中的几个示例给出了基本的使用,发现应用起来还是比较简单的,故对此开源项目进行了稍微全面一点的摸索吧,详细如下问所示。
Apache Commons Crypto 是Apache Commons下的子项目,是一个使用 AES-NI(高级加密标准新指令)优化的加密库。Commons Crypto 在密码级别和 Java 流级别提供 Java API。开发人员可以以最少的编码和工作量实现高性能 AES 加密/解密。请注意,Commons Crypto 没有直接实现 AES 等加密算法,它封装了 OpenSSL 和 JCE,以下几个方面为它的特征:
(1)用于低级加密操作的密码 API。
(2)安全的真随机数生成器。
(3)用于高级流加密/解密的 Java 流 API。
(4)使用英特尔 AES-NI 优化的高性能 AES 加密/解密。
(5)可跨多种操作系统移植(目前只有Linux/Mac OS/Windows);Apache Commons Crypto 根据您的机器环境(使用系统属性、os.name 和 os.arch)加载库。
(6)简单的用法,将 commons-crypto-(version).jar 文件添加到您的类路径中。
在学习该项目时主要建立在如何使用它提供的Api实现加密解密Api的层面上,至于项目源码可以从Apache Commons Crypto的官网和GitHub项目主页上下载,对于下载下来的代码主要关注其test目录中的examples包,经过实践发现,加密解密的实现可以重点参考以下3个示例,参考如下:
(1)CipherByteArrayExample:根据字节实现,无法对大文本进行加密和解密,代码示例中给出了固定长度32位的字节数组,经验证无法对超过此字节数组长度的文本进行加密,不推荐使用;
(2)CipherByteBufferExample:根据缓冲流实现,同样无法对大文本进行加密和解密,且代码示例的调用比较麻烦,不推荐使用;
(3)StreamExample:根据流实现,强烈建议使用这种方式,可以非常简单的对大文本实现加密和解密,本类源码提供的实现包含了加密和解密的逻辑,可以非常简单的进行二次的加密和解密的调用封装;
package org.apache.commons.crypto.examples;
import ...;
/**
* Example showing how to use stream encryption and decryption.
*/
public class StreamExample {
public static void main(final String []args) throws IOException {
final SecretKeySpec key = new SecretKeySpec(getUTF8Bytes("1234567890123456"),"AES");
final IvParameterSpec iv = new IvParameterSpec(getUTF8Bytes("1234567890123456"));
final Properties properties = new Properties();
final String transform = "AES/CBC/PKCS5Padding";
final String input = "hello world!";
//加密示例
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (CryptoOutputStream cos = new CryptoOutputStream(transform, properties, outputStream, key, iv)) {
cos.write(getUTF8Bytes(input));
cos.flush();
}
System.out.println("Encrypted: "+Arrays.toString(outputStream.toByteArray()));
// 解密示例
final InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
try (CryptoInputStream cis = new CryptoInputStream(transform, properties, inputStream, key, iv)) {
final byte[] decryptedData = new byte[1024];
int decryptedLen = 0;
int i;
while ((i = cis.read(decryptedData, decryptedLen, decryptedData.length - decryptedLen)) > -1) {
decryptedLen += i;
}
System.out.println("Decrypted: "+new String(decryptedData, 0, decryptedLen, StandardCharsets.UTF_8));
}
}
/**
* Converts String to UTF8 bytes
*
* @param input the input string
* @return UTF8 bytes
*/
private static byte[] getUTF8Bytes(final String input) {
return input.getBytes(StandardCharsets.UTF_8);
}
}
点赞