通过Cipher实现AES加密解密

/*
 * 注:utf-8是变长编码。
 * */
import java.lang.reflect.Parameter;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.junit.Test;

public class CipherTest {
    /**
     * 加密
     * @param params
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(String params) throws Exception {
        //密钥
        String keyStr = "孙悟空";
        Key key = CipherTest.getKey(keyStr);
        
        //加密/解密类
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//加密算法/操作模式/填充模式
        
        //初始化向量
        IvParameterSpec param = getParam("你是猴子请来的救兵吗");
        
        //初始化
        cipher.init(Cipher.ENCRYPT_MODE, key, param);
        
        return cipher.doFinal(params.getBytes());
    }
    
    /**
     * 解密
     * @param params
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] params) throws Exception {
        //密钥
        String keyStr = "孙悟空";
        Key key = getKey(keyStr);
        
        //加密/解密类
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        
        //初始化向量
        IvParameterSpec param = getParam("你是猴子请来的救兵吗");
        
        //初始化
        cipher.init(Cipher.DECRYPT_MODE, key, param);
        
        return cipher.doFinal(params);
    }
    
    public static Key getKey(String keyStr) {
        byte[] buff =keyStr.getBytes();
        byte[] temp=new byte[16];//默认为0
        for(int i=0;i<temp.length&&i<buff.length;++i) {
            temp[i]=buff[i];
        }
        return new SecretKeySpec(temp,"AES");
    }
    
    public static IvParameterSpec getParam(String keyStr) {
        byte[] buff =keyStr.getBytes();
        byte[] temp=new byte[16];//默认为0
        for(int i=0;i<temp.length&&i<buff.length;++i) {
            temp[i]=buff[i];
        }
        return new IvParameterSpec(temp);
    }
    
    @Test
    public void test() throws Exception {
        String params="我看你是在为难我胖虎";
        System.out.println("明文:"+params);
        
        byte[] paramsEn=encrypt(params);
        System.out.println("加密后:"+MyUtils.byte2Hex(paramsEn));
        
        byte[] paramsDe=decrypt(MyUtils.hex2Byte(MyUtils.byte2Hex(paramsEn)));
        System.out.println("解密后:"+new String(paramsDe));
    }
}

MyUtils中用到的方法

/**
     * 字节数组转为16进制字符串
     * 一个字节8位,对应2个16进制数
     * @param bytes
     * @return
     */
    public static String byte2Hex(byte[] bytes) {
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<bytes.length;++i) {
            String s=Integer.toHexString(bytes[i]&0xff);
            if(s.length()==1) {//高位是0的话
                s="0"+s;
            }
            sb.append(s);
        }
        return sb.toString().toUpperCase();
    }
    
    /**
     * 16进制字符串转为字节数组
     * 每2个16进制数作为一个字节
     * @param s
     * @return
     */
    public static byte[] hex2Byte(String s) {
        byte[] bytes=new byte[s.length()/2];
        for(int i=0;i<s.length()/2;++i) {
            bytes[i]=(byte)Integer.parseInt(s.substring(i*2, i*2+2),16);
        }
        return bytes;
    }

 注:

Integer.toHexString

Returns a string representation of the integer argument as an unsigned integer in base 16.

The unsigned integer value is the argument plus 232 if the argument is negative; otherwise, it is equal to the argument. This value is converted to a string of ASCII digits in hexadecimal (base 16) with no extra leading 0s. 

如果是负数的话,原本8位就变成了32位了,所以通过  bytes[i]&0xff  位操作,保留8位(2个f代表2位16进制)。

猜你喜欢

转载自www.cnblogs.com/xiangguoguo/p/9775194.html