zoukankan      html  css  js  c++  java
  • AES apache commons-crypto 对称加密

    apache实现的AES256加密

    官方用户指导链接:http://commons.apache.org/proper/commons-crypto/userguide.html

    官方字节缓存实现的例子链接:http://commons.apache.org/proper/commons-crypto/xref-test/org/apache/commons/crypto/examples/CipherByteBufferExample.html

    其实官方给了两种实现,另外一种是字节数组方式,如果加密的字符串过长,官方例子中的new的字节数组会异常,不如字节缓存方式更好。这里说下字节缓存的实现。

    官方例子的main方法是加密和解密一起处理的,不实际;我将官方例子中的main方法里的逻辑拆出来了加密和解密两个方法(注:@slf4j需要用到lombok,如果你没有引入,则把该注解去掉,修改代码中的log)

    package com.dmy.util;
    
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.crypto.cipher.CryptoCipher;
    import org.apache.commons.crypto.utils.Utils;
    import org.springframework.util.Base64Utils;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.ShortBufferException;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.nio.charset.StandardCharsets;
    import java.security.InvalidAlgorithmParameterException;
    import java.security.InvalidKeyException;
    import java.util.Properties;
    
    /**
     * Example showing the CryptoCipher API using a ByteBuffer
     */
    @Slf4j
    public class CipherByteBufferExample {
        //32字节长度的秘钥,也就是256位
        static final SecretKeySpec key = new SecretKeySpec(getUTF8Bytes("12345678901234561234567890123456"), "AES");
        //固定16字节长度
        static final IvParameterSpec iv = new IvParameterSpec(getUTF8Bytes("1234567890123456"));
        //加密方法/加密模式/填充方式,CBC是安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准
        static final String transform = "AES/CBC/PKCS5Padding";
    
        /**
         * Converts String to UTF8 bytes
         *
         * @param input the input string
         * @return UTF8 bytes
         */
        private static byte[] getUTF8Bytes(String input) {
            return input.getBytes(StandardCharsets.UTF_8);
        }
    
        /**
         * Converts ByteBuffer to String
         *
         * @param buffer input byte buffer
         * @return the converted string
         */
        private static String asString(ByteBuffer buffer) {
            final ByteBuffer copy = buffer.duplicate();
            final byte[] bytes = new byte[copy.remaining()];
            copy.get(bytes);
            return new String(bytes, StandardCharsets.UTF_8);
        }
    
        /**
         * 加密
         * @param text 需要加密的明文
         * @return 经过base64加密后的密文
         * @throws IOException
         * @throws InvalidAlgorithmParameterException
         * @throws InvalidKeyException
         * @throws ShortBufferException
         * @throws BadPaddingException
         * @throws IllegalBlockSizeException
         */
        public static String encrypt(String text) throws IOException, InvalidAlgorithmParameterException, InvalidKeyException, ShortBufferException, BadPaddingException, IllegalBlockSizeException {
            Properties properties = new Properties();
            final ByteBuffer outBuffer;
            final int bufferSize = 1024;
            final int updateBytes;
            final int finalBytes;
            //Creates a CryptoCipher instance with the transformation and properties.
            try (CryptoCipher encipher = Utils.getCipherInstance(transform, properties)) {
    
                ByteBuffer inBuffer = ByteBuffer.allocateDirect(bufferSize);
                outBuffer = ByteBuffer.allocateDirect(bufferSize);
                inBuffer.put(getUTF8Bytes(text));
    
                inBuffer.flip(); // ready for the cipher to read it
                // Show the data is there
                log.debug("inBuffer={}", asString(inBuffer));
    
                // Initializes the cipher with ENCRYPT_MODE,key and iv.
                encipher.init(Cipher.ENCRYPT_MODE, key, iv);
    
                // Continues a multiple-part encryption/decryption operation for byte buffer.
                updateBytes = encipher.update(inBuffer, outBuffer);
                log.debug("updateBytes={}", updateBytes);
    
                // We should call do final at the end of encryption/decryption.
                finalBytes = encipher.doFinal(inBuffer, outBuffer);
                log.debug("finalBytes={}", finalBytes);
            }
    
            outBuffer.flip(); // ready for use as decrypt
            byte[] encoded = new byte[updateBytes + finalBytes];
            outBuffer.duplicate().get(encoded);
            String encodedString = Base64Utils.encodeToString(encoded);
            log.debug("encodedString={}", encodedString);
            return encodedString;
        }
    
        /**
         * 解密
         * @param encodedString 经过base64加密后的密文
         * @return 明文
         * @throws IOException
         * @throws InvalidAlgorithmParameterException
         * @throws InvalidKeyException
         * @throws ShortBufferException
         * @throws BadPaddingException
         * @throws IllegalBlockSizeException
         */
        public static String dencrypt(String encodedString) throws IOException, InvalidAlgorithmParameterException, InvalidKeyException, ShortBufferException, BadPaddingException, IllegalBlockSizeException {
            Properties properties = new Properties();
            final ByteBuffer outBuffer;
            final int bufferSize = 1024;
            ByteBuffer decoded = ByteBuffer.allocateDirect(bufferSize);
            //Creates a CryptoCipher instance with the transformation and properties.
            try (CryptoCipher decipher = Utils.getCipherInstance(transform, properties)) {
                decipher.init(Cipher.DECRYPT_MODE, key, iv);
                outBuffer = ByteBuffer.allocateDirect(bufferSize);
                outBuffer.put(Base64Utils.decode(getUTF8Bytes(encodedString)));
                outBuffer.flip();
                decipher.update(outBuffer, decoded);
                decipher.doFinal(outBuffer, decoded);
                decoded.flip(); // ready for use
                log.debug("decoded={}", asString(decoded));
            }
    
            return asString(decoded);
        }
    
    }
  • 相关阅读:
    Java之多线程(实现Runnable接口)
    Java之使用HttpClient发送GET请求
    hbase中文内容编码转换
    Java之utf8中文编码转换
    Java之正则表达式
    Java之List排序功能举例
    maven测试时中文乱码问题解决方法
    Hbase之IP变更后无法启动问题解决
    Hbase远程连接:Can't get the locations
    重启Hbase命令
  • 原文地址:https://www.cnblogs.com/dingmy/p/9467429.html
Copyright © 2011-2022 走看看