【数据加密】AES加密和解密安卓篇(一)

来源:互联网 发布:杯装茶 知乎 编辑:程序博客网 时间:2024/05/18 09:02

1.什么是AES?

        高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

AES加密过程是在一个4×4的字节矩阵上运作,这个矩阵又称为“状态(state)”,其初值就是一个明文区块(矩阵中一个元素大小就是明文区块中的一个Byte)。(Rijndael加密法因支持更大的区块,其矩阵行数可视情况增加)加密时,各轮AES加密循环(除最后一轮外)均包含4个步骤:

  1. 1.AddRoundKey — 矩阵中的每一个字节都与该次轮秘钥(round key)做XOR运算;每个子密钥由密钥生成方案产生。
  1. 2.SubBytes — 通过个非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。

  1. 3.ShiftRows — 将矩阵中的每个横列进行循环式移位。
  2. 4.MixColumns — 为了充分混合矩阵中各个直行的操作。这个步骤使用线性转换来混合每列的四个字节。
最后一个加密循环中省略MixColumns步骤,而以另一个AddRoundKey取代。
效果图如下:
              
下面是操作类AESTools 
package yyc.com.htmltextview.AES;import java.io.UnsupportedEncodingException;import javax.crypto.Cipher;import javax.crypto.spec.SecretKeySpec;public class AesTools {    private static final String CipherMode = "AES/ECB/PKCS5Padding";    // 创建密钥    private static SecretKeySpec createKey(String password) {        byte[] data = null;  //        if (password == null) {            password = "";        }        StringBuffer sb = new StringBuffer(32);        sb.append(password);        while (sb.length() < 32) {            sb.append("0");        }        if (sb.length() > 32) {            sb.setLength(32);        }        try {            data = sb.toString().getBytes("UTF-8");//转成UTF-8型编码        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        }        return new SecretKeySpec(data, "AES");    }    public static byte[] encrypt(byte[] content, String password) {        try {            //  加密字节数据            SecretKeySpec key = createKey(password);            System.out.println(key);            Cipher cipher = Cipher.getInstance(CipherMode);            cipher.init(Cipher.ENCRYPT_MODE, key);            byte[] result = cipher.doFinal(content);            return result;        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    //  加密    public static String encrypt(String content, String password) {        byte[] data = null;        try {            data = content.getBytes("UTF-8");        } catch (Exception e) {            e.printStackTrace();        }        data = encrypt(data, password);        String result = byte2hex(data);        return result;//获得16进制数据    }    //  解密字节数组    public static byte[] decrypt(byte[] content, String password) {        try {            SecretKeySpec key = createKey(password);            Cipher cipher = Cipher.getInstance(CipherMode);            cipher.init(Cipher.DECRYPT_MODE, key);            //选择  类型            byte[] result = cipher.doFinal(content);            return result;        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    ///** 解密16进制的字符串为字符串 **/    public static String decrypt(String content, String password) {        byte[] data = null;        try {            data = hex2byte(content);        } catch (Exception e) {            e.printStackTrace();        }        data = decrypt(data, password);        if (data == null)            return null;        String result = null;        try {            result = new String(data, "UTF-8");//16进制结果        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        }        return result;    }    // /** 字节数组转成16进制字符串 **/    public static String byte2hex(byte[] b) { // 一个字节的数,        StringBuffer sb = new StringBuffer(b.length * 2);        String tmp = "";        for (int n = 0; n < b.length; n++) {//开始转化            // 整数转成十六进制表示            tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));            if (tmp.length() == 1) {                sb.append("0");            }            sb.append(tmp);        }        return sb.toString().toUpperCase(); // 转成大写    }    // 将hex字符串转换成字节数组    private static byte[] hex2byte(String inputString) {        if (inputString == null || inputString.length() < 2) {            return new byte[0];        }        inputString = inputString.toLowerCase();        int l = inputString.length() / 2;        byte[] result = new byte[l];        for (int i = 0; i < l; ++i) {            String tmp = inputString.substring(2 * i, 2 * i + 2);            result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);        }        return result;    }}
基本可以知道利用密钥对明文字符进行移位和替换操作


2 0