Apache Commons Crypto加密


placeholder image
admin 发布于:2022-06-19 21:58:11
阅读:loading

1.基本介绍

日常工作中会使用到的加密解密也是各种各样的,以本人来说文本编码(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 文件添加到您的类路径中。

2.源码项目介绍

在学习该项目时主要建立在如何使用它提供的Api实现加密解密Api的层面上,至于项目源码可以从Apache Commons Crypto的官网和GitHub项目主页上下载,对于下载下来的代码主要关注其test目录中的examples包,经过实践发现,加密解密的实现可以重点参考以下3个示例,参考如下:

(1)CipherByteArrayExample:根据字节实现,无法对大文本进行加密和解密,代码示例中给出了固定长度32位的字节数组,经验证无法对超过此字节数组长度的文本进行加密,不推荐使用;

(2)CipherByteBufferExample:根据缓冲流实现,同样无法对大文本进行加密和解密,且代码示例的调用比较麻烦,不推荐使用;

(3)StreamExample:根据流实现,强烈建议使用这种方式,可以非常简单的对大文本实现加密和解密,本类源码提供的实现包含了加密和解密的逻辑,可以非常简单的进行二次的加密和解密的调用封装;

image.png

3.推荐调用示例

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);
    }

}


 点赞


 发表评论

当前回复:作者

 评论列表


留言区