Android中AES加密算法

Android中AES的使用
常见的加密算法大致有两种,一种是对称加密算法如AES,另一种是非对称加密算法如RSA。在对称加密算法中,加密与解密的密钥是相同的。密钥是绝对不可以泄漏的,否则会被攻击者还原密文,窃取机密数据。非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。AES是对称加密算法的一种,对称加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦。

AES加密需要:明文 + 密钥+ 偏移量(IV)+密码模式(算法/模式/填充)
AES解密需要:密文 + 密钥+ 偏移量(IV)+密码模式(算法/模式/填充)

其中加密和解密的密钥,偏移量和密码模式要相同。实际工作中,对加密结果做Base64转换,在解密之前要做Base64逆转换。上代码:

import android.util.Base64;

import java.io.UnsupportedEncodingException;

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


public class AESUtil {
//-- 算法/模式/填充
 private static final String CipherMode = "AES/CBC/PKCS7Padding";

//--创建密钥
private static SecretKeySpec createKey(String password) {
    byte[] data = null;
    if (password == null) {
        password = "";
    }
    StringBuffer sb = new StringBuffer();
    sb.append(password);
    String s =null;
    while (sb.length() < 32) {
        sb.append(" ");//--密码长度不够32补足到32
    }
    s =sb.substring(0,32);//--截取32位密码
    try {
        data = s.getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return new SecretKeySpec(data, "AES");
}

//--创建偏移量
private static IvParameterSpec createIV(String iv) {
    byte[] data = null;
    if (iv == null) {
        iv = "";
    }
    StringBuffer sb = new StringBuffer(16);
    sb.append(iv);
    String s =null;
    while (sb.length() < 16) {
        sb.append(" ");//--偏移量长度不够16补足到16
    }
    s =sb.substring(0,16);//--截取16位偏移量
    try {
        data = s.getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return new IvParameterSpec(data);
}

//--加密字节数组到字节数组
public static byte[] encryptByte2Byte(byte[] content,String password,String iv){
    try {
        SecretKeySpec key = createKey(password);
        Cipher cipher = Cipher.getInstance(CipherMode);
        cipher.init(Cipher.ENCRYPT_MODE, key, createIV(iv));
        byte[] result = cipher.doFinal(content);
        return result;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
//--加密字节数组到字符串
public static String encryptByte2String(byte[] content,String password,String iv){
    byte[] data =encryptByte2Byte(content,password,iv);
    String result =new String(data);
    return  result;
}
//--加密字节数组到base64
public static String encryptByte2Base64(byte[] content,String password,String iv){
    byte[] data =encryptByte2Byte(content,password,iv);
    String result = new String(Base64.encode(data,Base64.DEFAULT));
    return result;
}

//--加密字符串到字节数组
public static byte[] encryptString2Byte(String content, String password, String iv){
    byte[] data = null;
    try {
        data = content.getBytes("UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    data = encryptByte2Byte(data,password,iv);
    return data;
}
//--加密字符串到字符串
public static String encryptString2String(String content, String password, String iv){
    byte[] data = null;
    try {
        data = content.getBytes("UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    data = encryptByte2Byte(data,password,iv);
    String result =new String(data);
    return result;
}
//--加密字符串到base64
public static String encryptString2Base64(String content, String password, String iv){
    byte[] data = null;
    try {
        data = content.getBytes("UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    data = encryptByte2Byte(data,password,iv);
    String result =new String(Base64.encode(data,Base64.DEFAULT));
    return result;
}

//-- 解密字节数组到字节数组
public static byte[] decryptByte2Byte(byte[] content, String password, String iv) {
    try {
        SecretKeySpec key = createKey(password);
        Cipher cipher = Cipher.getInstance(CipherMode);
        cipher.init(Cipher.DECRYPT_MODE, key, createIV(iv));
        byte[] result = cipher.doFinal(content);
        return result;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

//--解密字符串到字节数组
public static byte[] decryptString2Byte(String content, String password, String iv) {
    byte[] data = null;
    try {
        data = content.getBytes("UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    data = decryptByte2Byte(data,password,iv);
    return data;
}

//--解密base64到字节数组
public static byte[] decryptBase642Byte(String content, String password, String iv) {
    byte[] data = null;
    try {
        data = Base64.decode(content,Base64.DEFAULT);
    } catch (Exception e) {
        e.printStackTrace();
    }
    data = decryptByte2Byte(data,password,iv);
    return data;
}

//-- 解密字节数组到字符串
public static String decryptByte2String(byte[] content, String password, String iv) {
    byte[] data =decryptByte2Byte(content,password,iv);
    String result =new String(data);
    return result;
}

//-- 解密字节数组到字符串
public static String decryptBase642String(String content, String password, String iv) {
    byte[] data =Base64.decode(content,Base64.DEFAULT);
    String result=decryptByte2String(data,password,iv);
    return result;
}
}

AES加密的工具类AESUtil.java,封装了”AES/CBC/PKCS7Padding” 模式的加密方法。包括字节数组加密输出字节数组,字符串加密输出Base64等方法。

在实际工作中多是服务端使用密钥将字符串加密输出base64传递到客户端,客户端解密的时候,先将base64逆转换成字节数组,在使用ASE密钥解密得到解密后的字节数组,将解密后的字节数组转成字符串。

String base64String =AESUtil.encryptString2Base64("欢迎来到王者荣      耀","kakuishdyshifncgyrsjdiosfnvjfeas","asadfdedwderfvgd");
        LogUtil.i("load_Aes"," base64String "+base64String);//--U0E01UZ5ed7hijY7YY1+v/x5rsbWtknI9piWP3QHvfQ=

        String string  = AESUtil.decryptBase642String(base64String,"kakuishdyshifncgyrsjdiosfnvjfeas","asadfdedwderfvgd");
        LogUtil.i("load_Aes"," string "+string);//--欢迎来到王者荣耀

总结:上例先对字符串“欢迎来到王者荣耀”进行加密,输出base64,然后解密得到字符串“欢迎来到王者荣耀”。AES加密算法师对称加密算法,速度较快,在实际应用中较多。

你可能感兴趣的:(Android中AES加密算法)